CachedCall should let GC know to keep its arguments alive.
[WebKit-https.git] / Source / JavaScriptCore / runtime / VM.h
1 /*
2  * Copyright (C) 2008-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  *
8  * 1.  Redistributions of source code must retain the above copyright
9  *     notice, this list of conditions and the following disclaimer. 
10  * 2.  Redistributions in binary form must reproduce the above copyright
11  *     notice, this list of conditions and the following disclaimer in the
12  *     documentation and/or other materials provided with the distribution. 
13  * 3.  Neither the name of Apple Inc. ("Apple") nor the names of
14  *     its contributors may be used to endorse or promote products derived
15  *     from this software without specific prior written permission. 
16  *
17  * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
18  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20  * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
21  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
22  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
23  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
24  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27  */
28
29 #pragma once
30
31 #include "CallData.h"
32 #include "ConcurrentJSLock.h"
33 #include "ControlFlowProfiler.h"
34 #include "DateInstanceCache.h"
35 #include "DeleteAllCodeEffort.h"
36 #include "ExceptionEventLocation.h"
37 #include "ExecutableAllocator.h"
38 #include "FunctionHasExecutedCache.h"
39 #include "Heap.h"
40 #include "Intrinsic.h"
41 #include "JITThunks.h"
42 #include "JSCJSValue.h"
43 #include "JSDestructibleObjectSubspace.h"
44 #include "JSLock.h"
45 #include "JSSegmentedVariableObjectSubspace.h"
46 #include "JSStringSubspace.h"
47 #include "MacroAssemblerCodeRef.h"
48 #include "Microtask.h"
49 #include "NumericStrings.h"
50 #include "PrivateName.h"
51 #include "PrototypeMap.h"
52 #include "SmallStrings.h"
53 #include "SourceCode.h"
54 #include "Strong.h"
55 #include "Subspace.h"
56 #include "TemplateRegistryKeyTable.h"
57 #include "ThunkGenerators.h"
58 #include "VMEntryRecord.h"
59 #include "Watchpoint.h"
60 #include <wtf/Bag.h>
61 #include <wtf/BumpPointerAllocator.h>
62 #include <wtf/DateMath.h>
63 #include <wtf/Deque.h>
64 #include <wtf/DoublyLinkedList.h>
65 #include <wtf/Forward.h>
66 #include <wtf/HashMap.h>
67 #include <wtf/HashSet.h>
68 #include <wtf/StackBounds.h>
69 #include <wtf/Stopwatch.h>
70 #include <wtf/ThreadSafeRefCounted.h>
71 #include <wtf/ThreadSpecific.h>
72 #include <wtf/WTFThreadData.h>
73 #include <wtf/text/SymbolRegistry.h>
74 #include <wtf/text/WTFString.h>
75 #if ENABLE(REGEXP_TRACING)
76 #include <wtf/ListHashSet.h>
77 #endif
78
79 namespace WTF {
80 class SimpleStats;
81 } // namespace WTF
82 using WTF::SimpleStats;
83
84 namespace JSC {
85
86 class BuiltinExecutables;
87 class BytecodeIntrinsicRegistry;
88 class CodeBlock;
89 class CodeCache;
90 class CommonIdentifiers;
91 class CustomGetterSetter;
92 class ExecState;
93 class Exception;
94 class ExceptionScope;
95 class HandleStack;
96 class TypeProfiler;
97 class TypeProfilerLog;
98 class HasOwnPropertyCache;
99 class HeapProfiler;
100 class Identifier;
101 class Interpreter;
102 class JSCustomGetterSetterFunction;
103 class JSGlobalObject;
104 class JSObject;
105 class JSWebAssemblyInstance;
106 class LLIntOffsetsExtractor;
107 class NativeExecutable;
108 class RegExpCache;
109 class Register;
110 class RegisterAtOffsetList;
111 #if ENABLE(SAMPLING_PROFILER)
112 class SamplingProfiler;
113 #endif
114 class ShadowChicken;
115 class ScriptExecutable;
116 class SourceProvider;
117 class SourceProviderCache;
118 class StackFrame;
119 class Structure;
120 #if ENABLE(REGEXP_TRACING)
121 class RegExp;
122 #endif
123 class Symbol;
124 class TypedArrayController;
125 class UnlinkedCodeBlock;
126 class UnlinkedEvalCodeBlock;
127 class UnlinkedFunctionExecutable;
128 class UnlinkedProgramCodeBlock;
129 class UnlinkedModuleProgramCodeBlock;
130 class VirtualRegister;
131 class VMEntryScope;
132 class Watchdog;
133 class Watchpoint;
134 class WatchpointSet;
135
136 #if ENABLE(DFG_JIT)
137 namespace DFG {
138 class LongLivedState;
139 }
140 #endif // ENABLE(DFG_JIT)
141 #if ENABLE(FTL_JIT)
142 namespace FTL {
143 class Thunks;
144 }
145 #endif // ENABLE(FTL_JIT)
146 namespace CommonSlowPaths {
147 struct ArityCheckData;
148 }
149 namespace Profiler {
150 class Database;
151 }
152 namespace DOMJIT {
153 class Signature;
154 }
155 #if ENABLE(WEBASSEMBLY)
156 namespace Wasm {
157 class SignatureInformation;
158 }
159 #endif
160
161 struct HashTable;
162 struct Instruction;
163
164 struct LocalTimeOffsetCache {
165     LocalTimeOffsetCache()
166         : start(0.0)
167         , end(-1.0)
168         , increment(0.0)
169         , timeType(WTF::UTCTime)
170     {
171     }
172
173     void reset()
174     {
175         offset = LocalTimeOffset();
176         start = 0.0;
177         end = -1.0;
178         increment = 0.0;
179         timeType = WTF::UTCTime;
180     }
181
182     LocalTimeOffset offset;
183     double start;
184     double end;
185     double increment;
186     WTF::TimeType timeType;
187 };
188
189 class QueuedTask {
190     WTF_MAKE_NONCOPYABLE(QueuedTask);
191     WTF_MAKE_FAST_ALLOCATED;
192 public:
193     void run();
194
195     QueuedTask(VM& vm, JSGlobalObject* globalObject, Ref<Microtask>&& microtask)
196         : m_globalObject(vm, globalObject)
197         , m_microtask(WTFMove(microtask))
198     {
199     }
200
201 private:
202     Strong<JSGlobalObject> m_globalObject;
203     Ref<Microtask> m_microtask;
204 };
205
206 class ConservativeRoots;
207
208 #if COMPILER(MSVC)
209 #pragma warning(push)
210 #pragma warning(disable: 4200) // Disable "zero-sized array in struct/union" warning
211 #endif
212 struct ScratchBuffer {
213     ScratchBuffer()
214     {
215         u.m_activeLength = 0;
216     }
217
218     static ScratchBuffer* create(size_t size)
219     {
220         ScratchBuffer* result = new (fastMalloc(ScratchBuffer::allocationSize(size))) ScratchBuffer;
221
222         return result;
223     }
224
225     static size_t allocationSize(size_t bufferSize) { return sizeof(ScratchBuffer) + bufferSize; }
226     void setActiveLength(size_t activeLength) { u.m_activeLength = activeLength; }
227     size_t activeLength() const { return u.m_activeLength; };
228     size_t* activeLengthPtr() { return &u.m_activeLength; };
229     void* dataBuffer() { return m_buffer; }
230
231     union {
232         size_t m_activeLength;
233         double pad; // Make sure m_buffer is double aligned.
234     } u;
235 #if CPU(MIPS) && (defined WTF_MIPS_ARCH_REV && WTF_MIPS_ARCH_REV == 2)
236     void* m_buffer[0] __attribute__((aligned(8)));
237 #else
238     void* m_buffer[0];
239 #endif
240 };
241 #if COMPILER(MSVC)
242 #pragma warning(pop)
243 #endif
244
245 class VM : public ThreadSafeRefCounted<VM>, public DoublyLinkedListNode<VM> {
246 public:
247     // WebCore has a one-to-one mapping of threads to VMs;
248     // either create() or createLeaked() should only be called once
249     // on a thread, this is the 'default' VM (it uses the
250     // thread's default string uniquing table from wtfThreadData).
251     // API contexts created using the new context group aware interface
252     // create APIContextGroup objects which require less locking of JSC
253     // than the old singleton APIShared VM created for use by
254     // the original API.
255     enum VMType { Default, APIContextGroup, APIShared };
256
257     struct ClientData {
258         JS_EXPORT_PRIVATE virtual ~ClientData() = 0;
259     };
260
261     bool isSharedInstance() { return vmType == APIShared; }
262     bool usingAPI() { return vmType != Default; }
263     JS_EXPORT_PRIVATE static bool sharedInstanceExists();
264     JS_EXPORT_PRIVATE static VM& sharedInstance();
265
266     JS_EXPORT_PRIVATE static Ref<VM> create(HeapType = SmallHeap);
267     JS_EXPORT_PRIVATE static Ref<VM> createLeaked(HeapType = SmallHeap);
268     static Ref<VM> createContextGroup(HeapType = SmallHeap);
269     JS_EXPORT_PRIVATE ~VM();
270
271     JS_EXPORT_PRIVATE Watchdog& ensureWatchdog();
272     Watchdog* watchdog() { return m_watchdog.get(); }
273
274     HeapProfiler* heapProfiler() const { return m_heapProfiler.get(); }
275     JS_EXPORT_PRIVATE HeapProfiler& ensureHeapProfiler();
276
277 #if ENABLE(SAMPLING_PROFILER)
278     SamplingProfiler* samplingProfiler() { return m_samplingProfiler.get(); }
279     JS_EXPORT_PRIVATE SamplingProfiler& ensureSamplingProfiler(RefPtr<Stopwatch>&&);
280 #endif
281
282 private:
283     RefPtr<JSLock> m_apiLock;
284
285 public:
286 #if ENABLE(ASSEMBLER)
287     // executableAllocator should be destructed after the heap, as the heap can call executableAllocator
288     // in its destructor.
289     ExecutableAllocator executableAllocator;
290 #endif
291
292     // The heap should be just after executableAllocator and before other members to ensure that it's
293     // destructed after all the objects that reference it.
294     Heap heap;
295     
296     Subspace auxiliarySpace;
297     
298     // Whenever possible, use subspaceFor<CellType>(vm) to get one of these subspaces.
299     Subspace cellSpace;
300     Subspace destructibleCellSpace;
301     JSStringSubspace stringSpace;
302     JSDestructibleObjectSubspace destructibleObjectSpace;
303     JSSegmentedVariableObjectSubspace segmentedVariableObjectSpace;
304
305 #if ENABLE(DFG_JIT)
306     std::unique_ptr<DFG::LongLivedState> dfgState;
307 #endif // ENABLE(DFG_JIT)
308
309     VMType vmType;
310     ClientData* clientData;
311     VMEntryFrame* topVMEntryFrame;
312     // NOTE: When throwing an exception while rolling back the call frame, this may be equal to
313     // topVMEntryFrame.
314     // FIXME: This should be a void*, because it might not point to a CallFrame.
315     // https://bugs.webkit.org/show_bug.cgi?id=160441
316     ExecState* topCallFrame;
317     JSWebAssemblyInstance* topJSWebAssemblyInstance;
318     Strong<Structure> structureStructure;
319     Strong<Structure> structureRareDataStructure;
320     Strong<Structure> terminatedExecutionErrorStructure;
321     Strong<Structure> stringStructure;
322     Strong<Structure> propertyNameIteratorStructure;
323     Strong<Structure> propertyNameEnumeratorStructure;
324     Strong<Structure> customGetterSetterStructure;
325     Strong<Structure> scopedArgumentsTableStructure;
326     Strong<Structure> apiWrapperStructure;
327     Strong<Structure> JSScopeStructure;
328     Strong<Structure> executableStructure;
329     Strong<Structure> nativeExecutableStructure;
330     Strong<Structure> evalExecutableStructure;
331     Strong<Structure> programExecutableStructure;
332     Strong<Structure> functionExecutableStructure;
333 #if ENABLE(WEBASSEMBLY)
334     Strong<Structure> webAssemblyCalleeStructure;
335     Strong<Structure> webAssemblyToJSCalleeStructure;
336     Strong<JSCell> webAssemblyToJSCallee;
337 #endif
338     Strong<Structure> moduleProgramExecutableStructure;
339     Strong<Structure> regExpStructure;
340     Strong<Structure> symbolStructure;
341     Strong<Structure> symbolTableStructure;
342     Strong<Structure> fixedArrayStructure;
343     Strong<Structure> sourceCodeStructure;
344     Strong<Structure> scriptFetcherStructure;
345     Strong<Structure> structureChainStructure;
346     Strong<Structure> sparseArrayValueMapStructure;
347     Strong<Structure> templateRegistryKeyStructure;
348     Strong<Structure> arrayBufferNeuteringWatchpointStructure;
349     Strong<Structure> unlinkedFunctionExecutableStructure;
350     Strong<Structure> unlinkedProgramCodeBlockStructure;
351     Strong<Structure> unlinkedEvalCodeBlockStructure;
352     Strong<Structure> unlinkedFunctionCodeBlockStructure;
353     Strong<Structure> unlinkedModuleProgramCodeBlockStructure;
354     Strong<Structure> propertyTableStructure;
355     Strong<Structure> weakMapDataStructure;
356     Strong<Structure> inferredValueStructure;
357     Strong<Structure> inferredTypeStructure;
358     Strong<Structure> inferredTypeTableStructure;
359     Strong<Structure> functionRareDataStructure;
360     Strong<Structure> exceptionStructure;
361     Strong<Structure> promiseDeferredStructure;
362     Strong<Structure> internalPromiseDeferredStructure;
363     Strong<Structure> nativeStdFunctionCellStructure;
364     Strong<Structure> programCodeBlockStructure;
365     Strong<Structure> moduleProgramCodeBlockStructure;
366     Strong<Structure> evalCodeBlockStructure;
367     Strong<Structure> functionCodeBlockStructure;
368     Strong<Structure> hashMapBucketSetStructure;
369     Strong<Structure> hashMapBucketMapStructure;
370     Strong<Structure> hashMapImplSetStructure;
371     Strong<Structure> hashMapImplMapStructure;
372
373     Strong<JSCell> iterationTerminator;
374     Strong<JSCell> emptyPropertyNameEnumerator;
375
376 #if ENABLE(WEBASSEMBLY)
377     std::once_flag m_wasmSignatureInformationOnceFlag;
378     std::unique_ptr<Wasm::SignatureInformation> m_wasmSignatureInformation;
379 #endif
380     
381     JSCell* currentlyDestructingCallbackObject;
382     const ClassInfo* currentlyDestructingCallbackObjectClassInfo;
383
384     AtomicStringTable* m_atomicStringTable;
385     WTF::SymbolRegistry m_symbolRegistry;
386     TemplateRegistryKeyTable m_templateRegistryKeytable;
387     CommonIdentifiers* propertyNames;
388     const ArgList* emptyList;
389     SmallStrings smallStrings;
390     NumericStrings numericStrings;
391     DateInstanceCache dateInstanceCache;
392     std::unique_ptr<SimpleStats> machineCodeBytesPerBytecodeWordForBaselineJIT;
393     WeakGCMap<std::pair<CustomGetterSetter*, int>, JSCustomGetterSetterFunction> customGetterSetterFunctionMap;
394     WeakGCMap<StringImpl*, JSString, PtrHash<StringImpl*>> stringCache;
395     Strong<JSString> lastCachedString;
396
397     AtomicStringTable* atomicStringTable() const { return m_atomicStringTable; }
398     WTF::SymbolRegistry& symbolRegistry() { return m_symbolRegistry; }
399
400     TemplateRegistryKeyTable& templateRegistryKeyTable() { return m_templateRegistryKeytable; }
401
402     WeakGCMap<SymbolImpl*, Symbol, PtrHash<SymbolImpl*>> symbolImplToSymbolMap;
403
404     enum class DeletePropertyMode {
405         // Default behaviour of deleteProperty, matching the spec.
406         Default,
407         // This setting causes deleteProperty to force deletion of all
408         // properties including those that are non-configurable (DontDelete).
409         IgnoreConfigurable
410     };
411
412     DeletePropertyMode deletePropertyMode()
413     {
414         return m_deletePropertyMode;
415     }
416
417     class DeletePropertyModeScope {
418     public:
419         DeletePropertyModeScope(VM& vm, DeletePropertyMode mode)
420             : m_vm(vm)
421             , m_previousMode(vm.m_deletePropertyMode)
422         {
423             m_vm.m_deletePropertyMode = mode;
424         }
425
426         ~DeletePropertyModeScope()
427         {
428             m_vm.m_deletePropertyMode = m_previousMode;
429         }
430
431     private:
432         VM& m_vm;
433         DeletePropertyMode m_previousMode;
434     };
435
436 #if ENABLE(JIT)
437     bool canUseJIT() { return m_canUseJIT; }
438 #else
439     bool canUseJIT() { return false; } // interpreter only
440 #endif
441
442 #if ENABLE(YARR_JIT)
443     bool canUseRegExpJIT() { return m_canUseRegExpJIT; }
444 #else
445     bool canUseRegExpJIT() { return false; } // interpreter only
446 #endif
447
448     SourceProviderCache* addSourceProviderCache(SourceProvider*);
449     void clearSourceProviderCaches();
450
451     PrototypeMap prototypeMap;
452
453     typedef HashMap<RefPtr<SourceProvider>, RefPtr<SourceProviderCache>> SourceProviderCacheMap;
454     SourceProviderCacheMap sourceProviderCacheMap;
455     Interpreter* interpreter;
456 #if ENABLE(JIT)
457     std::unique_ptr<JITThunks> jitStubs;
458     MacroAssemblerCodeRef getCTIStub(ThunkGenerator generator)
459     {
460         return jitStubs->ctiStub(this, generator);
461     }
462     
463     std::unique_ptr<RegisterAtOffsetList> allCalleeSaveRegisterOffsets;
464     
465     RegisterAtOffsetList* getAllCalleeSaveRegisterOffsets() { return allCalleeSaveRegisterOffsets.get(); }
466
467 #endif // ENABLE(JIT)
468     std::unique_ptr<CommonSlowPaths::ArityCheckData> arityCheckData;
469 #if ENABLE(FTL_JIT)
470     std::unique_ptr<FTL::Thunks> ftlThunks;
471 #endif
472     NativeExecutable* getHostFunction(NativeFunction, NativeFunction constructor, const String& name);
473     NativeExecutable* getHostFunction(NativeFunction, Intrinsic, NativeFunction constructor, const DOMJIT::Signature*, const String& name);
474
475     static ptrdiff_t exceptionOffset()
476     {
477         return OBJECT_OFFSETOF(VM, m_exception);
478     }
479
480     static ptrdiff_t callFrameForCatchOffset()
481     {
482         return OBJECT_OFFSETOF(VM, callFrameForCatch);
483     }
484
485     static ptrdiff_t targetMachinePCForThrowOffset()
486     {
487         return OBJECT_OFFSETOF(VM, targetMachinePCForThrow);
488     }
489
490     void restorePreviousException(Exception* exception) { setException(exception); }
491
492     void clearLastException() { m_lastException = nullptr; }
493
494     ExecState** addressOfCallFrameForCatch() { return &callFrameForCatch; }
495
496     JSCell** addressOfException() { return reinterpret_cast<JSCell**>(&m_exception); }
497
498     Exception* lastException() const { return m_lastException; }
499     JSCell** addressOfLastException() { return reinterpret_cast<JSCell**>(&m_lastException); }
500
501     void setFailNextNewCodeBlock() { m_failNextNewCodeBlock = true; }
502     bool getAndClearFailNextNewCodeBlock()
503     {
504         bool result = m_failNextNewCodeBlock;
505         m_failNextNewCodeBlock = false;
506         return result;
507     }
508     
509     ALWAYS_INLINE Structure* getStructure(StructureID id)
510     {
511         return heap.structureIDTable().get(decontaminate(id));
512     }
513     
514     void* stackPointerAtVMEntry() const { return m_stackPointerAtVMEntry; }
515     void setStackPointerAtVMEntry(void*);
516
517     size_t softReservedZoneSize() const { return m_currentSoftReservedZoneSize; }
518     size_t updateSoftReservedZoneSize(size_t softReservedZoneSize);
519     
520     static size_t committedStackByteCount();
521     inline bool ensureStackCapacityFor(Register* newTopOfStack);
522
523     void* stackLimit() { return m_stackLimit; }
524     void* softStackLimit() { return m_softStackLimit; }
525     void** addressOfSoftStackLimit() { return &m_softStackLimit; }
526 #if !ENABLE(JIT)
527     void* cloopStackLimit() { return m_cloopStackLimit; }
528     void setCLoopStackLimit(void* limit) { m_cloopStackLimit = limit; }
529 #endif
530
531     inline bool isSafeToRecurseSoft() const;
532     bool isSafeToRecurse() const
533     {
534         return isSafeToRecurse(m_stackLimit);
535     }
536
537     void* lastStackTop() { return m_lastStackTop; }
538     void setLastStackTop(void*);
539
540     const ClassInfo* const jsArrayClassInfo;
541     const ClassInfo* const jsFinalObjectClassInfo;
542
543     JSValue hostCallReturnValue;
544     unsigned varargsLength;
545     ExecState* newCallFrameReturnValue;
546     ExecState* callFrameForCatch;
547     void* targetMachinePCForThrow;
548     Instruction* targetInterpreterPCForThrow;
549     uint32_t osrExitIndex;
550     void* osrExitJumpDestination;
551     Vector<ScratchBuffer*> scratchBuffers;
552     size_t sizeOfLastScratchBuffer;
553
554     bool isExecutingInRegExpJIT { false };
555
556     ScratchBuffer* scratchBufferForSize(size_t size)
557     {
558         if (!size)
559             return 0;
560
561         if (size > sizeOfLastScratchBuffer) {
562             // Protect against a N^2 memory usage pathology by ensuring
563             // that at worst, we get a geometric series, meaning that the
564             // total memory usage is somewhere around
565             // max(scratch buffer size) * 4.
566             sizeOfLastScratchBuffer = size * 2;
567
568             ScratchBuffer* newBuffer = ScratchBuffer::create(sizeOfLastScratchBuffer);
569             RELEASE_ASSERT(newBuffer);
570             scratchBuffers.append(newBuffer);
571         }
572
573         ScratchBuffer* result = scratchBuffers.last();
574         result->setActiveLength(0);
575         return result;
576     }
577
578     EncodedJSValue* exceptionFuzzingBuffer(size_t size)
579     {
580         ASSERT(Options::useExceptionFuzz());
581         if (!m_exceptionFuzzBuffer)
582             m_exceptionFuzzBuffer = MallocPtr<EncodedJSValue>::malloc(size);
583         return m_exceptionFuzzBuffer.get();
584     }
585
586     void gatherConservativeRoots(ConservativeRoots&);
587
588     VMEntryScope* entryScope;
589
590     JSObject* stringRecursionCheckFirstObject { nullptr };
591     HashSet<JSObject*> stringRecursionCheckVisitedObjects;
592
593     LocalTimeOffsetCache localTimeOffsetCache;
594
595     String cachedDateString;
596     double cachedDateStringValue;
597
598     std::unique_ptr<Profiler::Database> m_perBytecodeProfiler;
599     RefPtr<TypedArrayController> m_typedArrayController;
600     RegExpCache* m_regExpCache;
601     BumpPointerAllocator m_regExpAllocator;
602     ConcurrentJSLock m_regExpAllocatorLock;
603
604     std::unique_ptr<HasOwnPropertyCache> m_hasOwnPropertyCache;
605     ALWAYS_INLINE HasOwnPropertyCache* hasOwnPropertyCache() { return m_hasOwnPropertyCache.get(); }
606     HasOwnPropertyCache* ensureHasOwnPropertyCache();
607
608 #if ENABLE(REGEXP_TRACING)
609     typedef ListHashSet<RegExp*> RTTraceList;
610     RTTraceList* m_rtTraceList;
611 #endif
612
613     bool hasExclusiveThread() const { return m_apiLock->hasExclusiveThread(); }
614     std::thread::id exclusiveThread() const { return m_apiLock->exclusiveThread(); }
615     void setExclusiveThread(std::thread::id threadId) { m_apiLock->setExclusiveThread(threadId); }
616
617     JS_EXPORT_PRIVATE void resetDateCache();
618
619     RegExpCache* regExpCache() { return m_regExpCache; }
620 #if ENABLE(REGEXP_TRACING)
621     void addRegExpToTrace(RegExp*);
622 #endif
623     JS_EXPORT_PRIVATE void dumpRegExpTrace();
624
625     bool isCollectorBusyOnCurrentThread() { return heap.isCurrentThreadBusy(); }
626
627 #if ENABLE(GC_VALIDATION)
628     bool isInitializingObject() const; 
629     void setInitializingObjectClass(const ClassInfo*);
630 #endif
631
632     bool currentThreadIsHoldingAPILock() const { return m_apiLock->currentThreadIsHoldingLock(); }
633
634     JSLock& apiLock() { return *m_apiLock; }
635     CodeCache* codeCache() { return m_codeCache.get(); }
636
637     JS_EXPORT_PRIVATE void whenIdle(std::function<void()>);
638
639     JS_EXPORT_PRIVATE void deleteAllCode(DeleteAllCodeEffort);
640     JS_EXPORT_PRIVATE void deleteAllLinkedCode(DeleteAllCodeEffort);
641
642     WatchpointSet* ensureWatchpointSetForImpureProperty(const Identifier&);
643     void registerWatchpointForImpureProperty(const Identifier&, Watchpoint*);
644     
645     // FIXME: Use AtomicString once it got merged with Identifier.
646     JS_EXPORT_PRIVATE void addImpureProperty(const String&);
647
648     BuiltinExecutables* builtinExecutables() { return m_builtinExecutables.get(); }
649
650     bool enableTypeProfiler();
651     bool disableTypeProfiler();
652     TypeProfilerLog* typeProfilerLog() { return m_typeProfilerLog.get(); }
653     TypeProfiler* typeProfiler() { return m_typeProfiler.get(); }
654     JS_EXPORT_PRIVATE void dumpTypeProfilerData();
655
656     FunctionHasExecutedCache* functionHasExecutedCache() { return &m_functionHasExecutedCache; }
657
658     ControlFlowProfiler* controlFlowProfiler() { return m_controlFlowProfiler.get(); }
659     bool enableControlFlowProfiler();
660     bool disableControlFlowProfiler();
661
662     JS_EXPORT_PRIVATE void queueMicrotask(JSGlobalObject*, Ref<Microtask>&&);
663     JS_EXPORT_PRIVATE void drainMicrotasks();
664     void setGlobalConstRedeclarationShouldThrow(bool globalConstRedeclarationThrow) { m_globalConstRedeclarationShouldThrow = globalConstRedeclarationThrow; }
665     ALWAYS_INLINE bool globalConstRedeclarationShouldThrow() const { return m_globalConstRedeclarationShouldThrow; }
666
667     inline bool shouldTriggerTermination(ExecState*);
668
669     void setShouldBuildPCToCodeOriginMapping() { m_shouldBuildPCToCodeOriginMapping = true; }
670     bool shouldBuilderPCToCodeOriginMapping() const { return m_shouldBuildPCToCodeOriginMapping; }
671
672     BytecodeIntrinsicRegistry& bytecodeIntrinsicRegistry() { return *m_bytecodeIntrinsicRegistry; }
673     
674     ShadowChicken& shadowChicken() { return *m_shadowChicken; }
675     
676     template<typename Func>
677     void logEvent(CodeBlock*, const char* summary, const Func& func);
678
679 private:
680     friend class LLIntOffsetsExtractor;
681
682     VM(VMType, HeapType);
683     static VM*& sharedInstanceInternal();
684     void createNativeThunk();
685
686     void updateStackLimits();
687
688     bool isSafeToRecurse(void* stackLimit) const
689     {
690         ASSERT(wtfThreadData().stack().isGrowingDownward());
691         void* curr = reinterpret_cast<void*>(&curr);
692         return curr >= stackLimit;
693     }
694
695     void setException(Exception* exception)
696     {
697         m_exception = exception;
698         m_lastException = exception;
699     }
700     Exception* exception() const
701     {
702 #if ENABLE(EXCEPTION_SCOPE_VERIFICATION)
703         m_needExceptionCheck = false;
704 #endif
705         return m_exception;
706     }
707     void clearException()
708     {
709 #if ENABLE(EXCEPTION_SCOPE_VERIFICATION)
710         m_needExceptionCheck = false;
711 #endif
712         m_exception = nullptr;
713     }
714
715 #if !ENABLE(JIT)    
716     bool ensureStackCapacityForCLoop(Register* newTopOfStack);
717     bool isSafeToRecurseSoftCLoop() const;
718 #endif // !ENABLE(JIT)
719
720     JS_EXPORT_PRIVATE void throwException(ExecState*, Exception*);
721     JS_EXPORT_PRIVATE JSValue throwException(ExecState*, JSValue);
722     JS_EXPORT_PRIVATE JSObject* throwException(ExecState*, JSObject*);
723
724 #if ENABLE(EXCEPTION_SCOPE_VERIFICATION)
725     void verifyExceptionCheckNeedIsSatisfied(unsigned depth, ExceptionEventLocation&);
726 #endif
727
728 #if ENABLE(ASSEMBLER)
729     bool m_canUseAssembler;
730 #endif
731 #if ENABLE(JIT)
732     bool m_canUseJIT;
733 #endif
734 #if ENABLE(YARR_JIT)
735     bool m_canUseRegExpJIT;
736 #endif
737 #if ENABLE(GC_VALIDATION)
738     const ClassInfo* m_initializingObjectClass;
739 #endif
740
741     void* m_stackPointerAtVMEntry;
742     size_t m_currentSoftReservedZoneSize;
743     void* m_stackLimit { nullptr };
744     void* m_softStackLimit { nullptr };
745 #if !ENABLE(JIT)
746     void* m_cloopStackLimit { nullptr };
747 #endif
748     void* m_lastStackTop;
749
750     Exception* m_exception { nullptr };
751     Exception* m_lastException { nullptr };
752 #if ENABLE(EXCEPTION_SCOPE_VERIFICATION)
753     ExceptionScope* m_topExceptionScope { nullptr };
754     ExceptionEventLocation m_simulatedThrowPointLocation;
755     unsigned m_simulatedThrowPointRecursionDepth { 0 };
756     mutable bool m_needExceptionCheck { false };
757 #endif
758
759     bool m_failNextNewCodeBlock { false };
760     DeletePropertyMode m_deletePropertyMode { DeletePropertyMode::Default };
761     bool m_globalConstRedeclarationShouldThrow { true };
762     bool m_shouldBuildPCToCodeOriginMapping { false };
763     std::unique_ptr<CodeCache> m_codeCache;
764     std::unique_ptr<BuiltinExecutables> m_builtinExecutables;
765     HashMap<String, RefPtr<WatchpointSet>> m_impurePropertyWatchpointSets;
766     std::unique_ptr<TypeProfiler> m_typeProfiler;
767     std::unique_ptr<TypeProfilerLog> m_typeProfilerLog;
768     unsigned m_typeProfilerEnabledCount;
769     FunctionHasExecutedCache m_functionHasExecutedCache;
770     std::unique_ptr<ControlFlowProfiler> m_controlFlowProfiler;
771     unsigned m_controlFlowProfilerEnabledCount;
772     Deque<std::unique_ptr<QueuedTask>> m_microtaskQueue;
773     MallocPtr<EncodedJSValue> m_exceptionFuzzBuffer;
774     RefPtr<Watchdog> m_watchdog;
775     std::unique_ptr<HeapProfiler> m_heapProfiler;
776 #if ENABLE(SAMPLING_PROFILER)
777     RefPtr<SamplingProfiler> m_samplingProfiler;
778 #endif
779     std::unique_ptr<ShadowChicken> m_shadowChicken;
780     std::unique_ptr<BytecodeIntrinsicRegistry> m_bytecodeIntrinsicRegistry;
781
782     VM* m_prev; // Required by DoublyLinkedListNode.
783     VM* m_next; // Required by DoublyLinkedListNode.
784
785     // Friends for exception checking purpose only.
786     friend class Heap;
787     friend class CatchScope;
788     friend class ExceptionScope;
789     friend class ThrowScope;
790     friend class WTF::DoublyLinkedListNode<VM>;
791 };
792
793 #if ENABLE(GC_VALIDATION)
794 inline bool VM::isInitializingObject() const
795 {
796     return !!m_initializingObjectClass;
797 }
798
799 inline void VM::setInitializingObjectClass(const ClassInfo* initializingObjectClass)
800 {
801     m_initializingObjectClass = initializingObjectClass;
802 }
803 #endif
804
805 inline Heap* WeakSet::heap() const
806 {
807     return &m_vm->heap;
808 }
809
810 #if ENABLE(JIT)
811 extern "C" void sanitizeStackForVMImpl(VM*);
812 #endif
813
814 void sanitizeStackForVM(VM*);
815 void logSanitizeStack(VM*);
816
817 } // namespace JSC