Implement try/catch in the DFG.
[WebKit-https.git] / Source / JavaScriptCore / bytecode / CodeBlock.h
1 /*
2  * Copyright (C) 2008-2015 Apple Inc. All rights reserved.
3  * Copyright (C) 2008 Cameron Zwarich <cwzwarich@uwaterloo.ca>
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  *
9  * 1.  Redistributions of source code must retain the above copyright
10  *     notice, this list of conditions and the following disclaimer.
11  * 2.  Redistributions in binary form must reproduce the above copyright
12  *     notice, this list of conditions and the following disclaimer in the
13  *     documentation and/or other materials provided with the distribution.
14  * 3.  Neither the name of Apple Inc. ("Apple") nor the names of
15  *     its contributors may be used to endorse or promote products derived
16  *     from this software without specific prior written permission.
17  *
18  * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
19  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21  * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
22  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
24  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
25  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28  */
29
30 #ifndef CodeBlock_h
31 #define CodeBlock_h
32
33 #include "ArrayProfile.h"
34 #include "ByValInfo.h"
35 #include "BytecodeConventions.h"
36 #include "BytecodeLivenessAnalysis.h"
37 #include "CallLinkInfo.h"
38 #include "CallReturnOffsetToBytecodeOffset.h"
39 #include "CodeBlockHash.h"
40 #include "CodeBlockSet.h"
41 #include "ConcurrentJITLock.h"
42 #include "CodeOrigin.h"
43 #include "CodeType.h"
44 #include "CompactJITCodeMap.h"
45 #include "DFGCommon.h"
46 #include "DFGCommonData.h"
47 #include "DFGExitProfile.h"
48 #include "DeferredCompilationCallback.h"
49 #include "EvalCodeCache.h"
50 #include "ExecutionCounter.h"
51 #include "ExpressionRangeInfo.h"
52 #include "HandlerInfo.h"
53 #include "ObjectAllocationProfile.h"
54 #include "Options.h"
55 #include "PutPropertySlot.h"
56 #include "Instruction.h"
57 #include "JITCode.h"
58 #include "JITWriteBarrier.h"
59 #include "JSGlobalObject.h"
60 #include "JumpTable.h"
61 #include "LLIntCallLinkInfo.h"
62 #include "LazyOperandValueProfile.h"
63 #include "ProfilerCompilation.h"
64 #include "ProfilerJettisonReason.h"
65 #include "RegExpObject.h"
66 #include "StructureStubInfo.h"
67 #include "UnconditionalFinalizer.h"
68 #include "ValueProfile.h"
69 #include "VirtualRegister.h"
70 #include "Watchpoint.h"
71 #include <wtf/Bag.h>
72 #include <wtf/FastMalloc.h>
73 #include <wtf/RefCountedArray.h>
74 #include <wtf/RefPtr.h>
75 #include <wtf/SegmentedVector.h>
76 #include <wtf/Vector.h>
77 #include <wtf/text/WTFString.h>
78
79 namespace JSC {
80
81 class ExecState;
82 class LLIntOffsetsExtractor;
83 class RegisterAtOffsetList;
84 class TypeLocation;
85 class JSModuleEnvironment;
86
87 enum ReoptimizationMode { DontCountReoptimization, CountReoptimization };
88
89 class CodeBlock : public ThreadSafeRefCounted<CodeBlock>, public UnconditionalFinalizer, public WeakReferenceHarvester {
90     WTF_MAKE_FAST_ALLOCATED;
91     friend class BytecodeLivenessAnalysis;
92     friend class JIT;
93     friend class LLIntOffsetsExtractor;
94 public:
95     enum CopyParsedBlockTag { CopyParsedBlock };
96 protected:
97     CodeBlock(CopyParsedBlockTag, CodeBlock& other);
98         
99     CodeBlock(ScriptExecutable* ownerExecutable, UnlinkedCodeBlock*, JSScope*, PassRefPtr<SourceProvider>, unsigned sourceOffset, unsigned firstLineColumnOffset);
100 #if ENABLE(WEBASSEMBLY)
101     CodeBlock(WebAssemblyExecutable* ownerExecutable, VM&, JSGlobalObject*);
102 #endif
103
104     WriteBarrier<JSGlobalObject> m_globalObject;
105     Heap* m_heap;
106
107 public:
108     JS_EXPORT_PRIVATE virtual ~CodeBlock();
109
110     UnlinkedCodeBlock* unlinkedCodeBlock() const { return m_unlinkedCode.get(); }
111
112     CString inferredName() const;
113     CodeBlockHash hash() const;
114     bool hasHash() const;
115     bool isSafeToComputeHash() const;
116     CString hashAsStringIfPossible() const;
117     CString sourceCodeForTools() const; // Not quite the actual source we parsed; this will do things like prefix the source for a function with a reified signature.
118     CString sourceCodeOnOneLine() const; // As sourceCodeForTools(), but replaces all whitespace runs with a single space.
119     void dumpAssumingJITType(PrintStream&, JITCode::JITType) const;
120     void dump(PrintStream&) const;
121
122     int numParameters() const { return m_numParameters; }
123     void setNumParameters(int newValue);
124
125     int* addressOfNumParameters() { return &m_numParameters; }
126     static ptrdiff_t offsetOfNumParameters() { return OBJECT_OFFSETOF(CodeBlock, m_numParameters); }
127
128     CodeBlock* alternative() { return m_alternative.get(); }
129     void setAlternative(PassRefPtr<CodeBlock> alternative) { m_alternative = alternative; }
130
131     template <typename Functor> void forEachRelatedCodeBlock(Functor&& functor)
132     {
133         Functor f(std::forward<Functor>(functor));
134         Vector<CodeBlock*, 4> codeBlocks;
135         codeBlocks.append(this);
136
137         while (!codeBlocks.isEmpty()) {
138             CodeBlock* currentCodeBlock = codeBlocks.takeLast();
139             f(currentCodeBlock);
140
141             if (CodeBlock* alternative = currentCodeBlock->alternative())
142                 codeBlocks.append(alternative);
143             if (CodeBlock* osrEntryBlock = currentCodeBlock->specialOSREntryBlockOrNull())
144                 codeBlocks.append(osrEntryBlock);
145         }
146     }
147     
148     CodeSpecializationKind specializationKind() const
149     {
150         return specializationFromIsConstruct(m_isConstructor);
151     }
152     
153     CodeBlock* baselineAlternative();
154     
155     // FIXME: Get rid of this.
156     // https://bugs.webkit.org/show_bug.cgi?id=123677
157     CodeBlock* baselineVersion();
158
159     void clearMarks();
160     void visitAggregate(SlotVisitor&);
161     void visitStrongly(SlotVisitor&);
162
163     void dumpSource();
164     void dumpSource(PrintStream&);
165
166     void dumpBytecode();
167     void dumpBytecode(PrintStream&);
168     void dumpBytecode(
169         PrintStream&, unsigned bytecodeOffset,
170         const StubInfoMap& = StubInfoMap(), const CallLinkInfoMap& = CallLinkInfoMap());
171     void printStructures(PrintStream&, const Instruction*);
172     void printStructure(PrintStream&, const char* name, const Instruction*, int operand);
173
174     bool isStrictMode() const { return m_isStrictMode; }
175     ECMAMode ecmaMode() const { return isStrictMode() ? StrictMode : NotStrictMode; }
176
177     inline bool isKnownNotImmediate(int index)
178     {
179         if (index == m_thisRegister.offset() && !m_isStrictMode)
180             return true;
181
182         if (isConstantRegisterIndex(index))
183             return getConstant(index).isCell();
184
185         return false;
186     }
187
188     ALWAYS_INLINE bool isTemporaryRegisterIndex(int index)
189     {
190         return index >= m_numVars;
191     }
192
193     enum class RequiredHandler {
194         CatchHandler,
195         AnyHandler
196     };
197     HandlerInfo* handlerForBytecodeOffset(unsigned bytecodeOffset, RequiredHandler = RequiredHandler::AnyHandler);
198     HandlerInfo* handlerForIndex(unsigned, RequiredHandler = RequiredHandler::AnyHandler);
199     unsigned lineNumberForBytecodeOffset(unsigned bytecodeOffset);
200     unsigned columnNumberForBytecodeOffset(unsigned bytecodeOffset);
201     void expressionRangeForBytecodeOffset(unsigned bytecodeOffset, int& divot,
202                                           int& startOffset, int& endOffset, unsigned& line, unsigned& column);
203
204     void getStubInfoMap(const ConcurrentJITLocker&, StubInfoMap& result);
205     void getStubInfoMap(StubInfoMap& result);
206     
207     void getCallLinkInfoMap(const ConcurrentJITLocker&, CallLinkInfoMap& result);
208     void getCallLinkInfoMap(CallLinkInfoMap& result);
209
210     void getByValInfoMap(const ConcurrentJITLocker&, ByValInfoMap& result);
211     void getByValInfoMap(ByValInfoMap& result);
212     
213 #if ENABLE(JIT)
214     StructureStubInfo* addStubInfo(AccessType);
215     Bag<StructureStubInfo>::iterator stubInfoBegin() { return m_stubInfos.begin(); }
216     Bag<StructureStubInfo>::iterator stubInfoEnd() { return m_stubInfos.end(); }
217     
218     // O(n) operation. Use getStubInfoMap() unless you really only intend to get one
219     // stub info.
220     StructureStubInfo* findStubInfo(CodeOrigin);
221
222     ByValInfo* addByValInfo();
223
224     CallLinkInfo* addCallLinkInfo();
225     Bag<CallLinkInfo>::iterator callLinkInfosBegin() { return m_callLinkInfos.begin(); }
226     Bag<CallLinkInfo>::iterator callLinkInfosEnd() { return m_callLinkInfos.end(); }
227
228     // This is a slow function call used primarily for compiling OSR exits in the case
229     // that there had been inlining. Chances are if you want to use this, you're really
230     // looking for a CallLinkInfoMap to amortize the cost of calling this.
231     CallLinkInfo* getCallLinkInfoForBytecodeIndex(unsigned bytecodeIndex);
232 #endif // ENABLE(JIT)
233
234     void unlinkIncomingCalls();
235
236 #if ENABLE(JIT)
237     void linkIncomingCall(ExecState* callerFrame, CallLinkInfo*);
238     void linkIncomingPolymorphicCall(ExecState* callerFrame, PolymorphicCallNode*);
239 #endif // ENABLE(JIT)
240
241     void linkIncomingCall(ExecState* callerFrame, LLIntCallLinkInfo*);
242
243     void setJITCodeMap(std::unique_ptr<CompactJITCodeMap> jitCodeMap)
244     {
245         m_jitCodeMap = WTF::move(jitCodeMap);
246     }
247     CompactJITCodeMap* jitCodeMap()
248     {
249         return m_jitCodeMap.get();
250     }
251     
252     unsigned bytecodeOffset(Instruction* returnAddress)
253     {
254         RELEASE_ASSERT(returnAddress >= instructions().begin() && returnAddress < instructions().end());
255         return static_cast<Instruction*>(returnAddress) - instructions().begin();
256     }
257
258     unsigned numberOfInstructions() const { return m_instructions.size(); }
259     RefCountedArray<Instruction>& instructions() { return m_instructions; }
260     const RefCountedArray<Instruction>& instructions() const { return m_instructions; }
261
262     size_t predictedMachineCodeSize();
263
264     bool usesOpcode(OpcodeID);
265
266     unsigned instructionCount() const { return m_instructions.size(); }
267
268     // Exactly equivalent to codeBlock->ownerExecutable()->newReplacementCodeBlockFor(codeBlock->specializationKind())
269     PassRefPtr<CodeBlock> newReplacement();
270     
271     void setJITCode(PassRefPtr<JITCode> code)
272     {
273         ASSERT(m_heap->isDeferred());
274         m_heap->reportExtraMemoryAllocated(code->size());
275         ConcurrentJITLocker locker(m_lock);
276         WTF::storeStoreFence(); // This is probably not needed because the lock will also do something similar, but it's good to be paranoid.
277         m_jitCode = code;
278     }
279     PassRefPtr<JITCode> jitCode() { return m_jitCode; }
280     JITCode::JITType jitType() const
281     {
282         JITCode* jitCode = m_jitCode.get();
283         WTF::loadLoadFence();
284         JITCode::JITType result = JITCode::jitTypeFor(jitCode);
285         WTF::loadLoadFence(); // This probably isn't needed. Oh well, paranoia is good.
286         return result;
287     }
288
289     bool hasBaselineJITProfiling() const
290     {
291         return jitType() == JITCode::BaselineJIT;
292     }
293     
294 #if ENABLE(JIT)
295     virtual CodeBlock* replacement() = 0;
296
297     virtual DFG::CapabilityLevel capabilityLevelInternal() = 0;
298     DFG::CapabilityLevel capabilityLevel();
299     DFG::CapabilityLevel capabilityLevelState() { return m_capabilityLevelState; }
300
301     bool hasOptimizedReplacement(JITCode::JITType typeToReplace);
302     bool hasOptimizedReplacement(); // the typeToReplace is my JITType
303 #endif
304
305     void jettison(Profiler::JettisonReason, ReoptimizationMode = DontCountReoptimization, const FireDetail* = nullptr);
306     
307     ExecutableBase* ownerExecutable() const { return m_ownerExecutable.get(); }
308     ScriptExecutable* ownerScriptExecutable() const { return jsCast<ScriptExecutable*>(m_ownerExecutable.get()); }
309
310     void setVM(VM* vm) { m_vm = vm; }
311     VM* vm() { return m_vm; }
312
313     void setThisRegister(VirtualRegister thisRegister) { m_thisRegister = thisRegister; }
314     VirtualRegister thisRegister() const { return m_thisRegister; }
315
316     bool usesEval() const { return m_unlinkedCode->usesEval(); }
317
318     void setScopeRegister(VirtualRegister scopeRegister)
319     {
320         ASSERT(scopeRegister.isLocal() || !scopeRegister.isValid());
321         m_scopeRegister = scopeRegister;
322     }
323
324     VirtualRegister scopeRegister() const
325     {
326         return m_scopeRegister;
327     }
328
329     void setActivationRegister(VirtualRegister activationRegister)
330     {
331         m_lexicalEnvironmentRegister = activationRegister;
332     }
333
334     VirtualRegister activationRegister() const
335     {
336         ASSERT(m_lexicalEnvironmentRegister.isValid());
337         return m_lexicalEnvironmentRegister;
338     }
339
340     VirtualRegister uncheckedActivationRegister()
341     {
342         return m_lexicalEnvironmentRegister;
343     }
344
345     bool needsActivation() const
346     {
347         ASSERT(m_lexicalEnvironmentRegister.isValid() == m_needsActivation);
348         return m_needsActivation;
349     }
350     
351     CodeType codeType() const
352     {
353         return m_codeType;
354     }
355
356     PutPropertySlot::Context putByIdContext() const
357     {
358         if (codeType() == EvalCode)
359             return PutPropertySlot::PutByIdEval;
360         return PutPropertySlot::PutById;
361     }
362
363     SourceProvider* source() const { return m_source.get(); }
364     unsigned sourceOffset() const { return m_sourceOffset; }
365     unsigned firstLineColumnOffset() const { return m_firstLineColumnOffset; }
366
367     size_t numberOfJumpTargets() const { return m_unlinkedCode->numberOfJumpTargets(); }
368     unsigned jumpTarget(int index) const { return m_unlinkedCode->jumpTarget(index); }
369
370     String nameForRegister(VirtualRegister);
371
372     unsigned numberOfArgumentValueProfiles()
373     {
374         ASSERT(m_numParameters >= 0);
375         ASSERT(m_argumentValueProfiles.size() == static_cast<unsigned>(m_numParameters));
376         return m_argumentValueProfiles.size();
377     }
378     ValueProfile* valueProfileForArgument(unsigned argumentIndex)
379     {
380         ValueProfile* result = &m_argumentValueProfiles[argumentIndex];
381         ASSERT(result->m_bytecodeOffset == -1);
382         return result;
383     }
384
385     unsigned numberOfValueProfiles() { return m_valueProfiles.size(); }
386     ValueProfile* valueProfile(int index) { return &m_valueProfiles[index]; }
387     ValueProfile* valueProfileForBytecodeOffset(int bytecodeOffset);
388     SpeculatedType valueProfilePredictionForBytecodeOffset(const ConcurrentJITLocker& locker, int bytecodeOffset)
389     {
390         return valueProfileForBytecodeOffset(bytecodeOffset)->computeUpdatedPrediction(locker);
391     }
392
393     unsigned totalNumberOfValueProfiles()
394     {
395         return numberOfArgumentValueProfiles() + numberOfValueProfiles();
396     }
397     ValueProfile* getFromAllValueProfiles(unsigned index)
398     {
399         if (index < numberOfArgumentValueProfiles())
400             return valueProfileForArgument(index);
401         return valueProfile(index - numberOfArgumentValueProfiles());
402     }
403
404     RareCaseProfile* addRareCaseProfile(int bytecodeOffset)
405     {
406         m_rareCaseProfiles.append(RareCaseProfile(bytecodeOffset));
407         return &m_rareCaseProfiles.last();
408     }
409     unsigned numberOfRareCaseProfiles() { return m_rareCaseProfiles.size(); }
410     RareCaseProfile* rareCaseProfile(int index) { return &m_rareCaseProfiles[index]; }
411     RareCaseProfile* rareCaseProfileForBytecodeOffset(int bytecodeOffset);
412
413     bool likelyToTakeSlowCase(int bytecodeOffset)
414     {
415         if (!hasBaselineJITProfiling())
416             return false;
417         unsigned value = rareCaseProfileForBytecodeOffset(bytecodeOffset)->m_counter;
418         return value >= Options::likelyToTakeSlowCaseMinimumCount();
419     }
420
421     bool couldTakeSlowCase(int bytecodeOffset)
422     {
423         if (!hasBaselineJITProfiling())
424             return false;
425         unsigned value = rareCaseProfileForBytecodeOffset(bytecodeOffset)->m_counter;
426         return value >= Options::couldTakeSlowCaseMinimumCount();
427     }
428
429     RareCaseProfile* addSpecialFastCaseProfile(int bytecodeOffset)
430     {
431         m_specialFastCaseProfiles.append(RareCaseProfile(bytecodeOffset));
432         return &m_specialFastCaseProfiles.last();
433     }
434     unsigned numberOfSpecialFastCaseProfiles() { return m_specialFastCaseProfiles.size(); }
435     RareCaseProfile* specialFastCaseProfile(int index) { return &m_specialFastCaseProfiles[index]; }
436     RareCaseProfile* specialFastCaseProfileForBytecodeOffset(int bytecodeOffset)
437     {
438         return tryBinarySearch<RareCaseProfile, int>(
439             m_specialFastCaseProfiles, m_specialFastCaseProfiles.size(), bytecodeOffset,
440             getRareCaseProfileBytecodeOffset);
441     }
442
443     bool likelyToTakeSpecialFastCase(int bytecodeOffset)
444     {
445         if (!hasBaselineJITProfiling())
446             return false;
447         unsigned specialFastCaseCount = specialFastCaseProfileForBytecodeOffset(bytecodeOffset)->m_counter;
448         return specialFastCaseCount >= Options::likelyToTakeSlowCaseMinimumCount();
449     }
450
451     bool couldTakeSpecialFastCase(int bytecodeOffset)
452     {
453         if (!hasBaselineJITProfiling())
454             return false;
455         unsigned specialFastCaseCount = specialFastCaseProfileForBytecodeOffset(bytecodeOffset)->m_counter;
456         return specialFastCaseCount >= Options::couldTakeSlowCaseMinimumCount();
457     }
458
459     bool likelyToTakeDeepestSlowCase(int bytecodeOffset)
460     {
461         if (!hasBaselineJITProfiling())
462             return false;
463         unsigned slowCaseCount = rareCaseProfileForBytecodeOffset(bytecodeOffset)->m_counter;
464         unsigned specialFastCaseCount = specialFastCaseProfileForBytecodeOffset(bytecodeOffset)->m_counter;
465         unsigned value = slowCaseCount - specialFastCaseCount;
466         return value >= Options::likelyToTakeSlowCaseMinimumCount();
467     }
468
469     bool likelyToTakeAnySlowCase(int bytecodeOffset)
470     {
471         if (!hasBaselineJITProfiling())
472             return false;
473         unsigned slowCaseCount = rareCaseProfileForBytecodeOffset(bytecodeOffset)->m_counter;
474         unsigned specialFastCaseCount = specialFastCaseProfileForBytecodeOffset(bytecodeOffset)->m_counter;
475         unsigned value = slowCaseCount + specialFastCaseCount;
476         return value >= Options::likelyToTakeSlowCaseMinimumCount();
477     }
478
479     unsigned numberOfArrayProfiles() const { return m_arrayProfiles.size(); }
480     const ArrayProfileVector& arrayProfiles() { return m_arrayProfiles; }
481     ArrayProfile* addArrayProfile(unsigned bytecodeOffset)
482     {
483         m_arrayProfiles.append(ArrayProfile(bytecodeOffset));
484         return &m_arrayProfiles.last();
485     }
486     ArrayProfile* getArrayProfile(unsigned bytecodeOffset);
487     ArrayProfile* getOrAddArrayProfile(unsigned bytecodeOffset);
488
489     // Exception handling support
490
491     size_t numberOfExceptionHandlers() const { return m_rareData ? m_rareData->m_exceptionHandlers.size() : 0; }
492     HandlerInfo& exceptionHandler(int index) { RELEASE_ASSERT(m_rareData); return m_rareData->m_exceptionHandlers[index]; }
493
494     bool hasExpressionInfo() { return m_unlinkedCode->hasExpressionInfo(); }
495
496 #if ENABLE(DFG_JIT)
497     Vector<CodeOrigin, 0, UnsafeVectorOverflow>& codeOrigins()
498     {
499         return m_jitCode->dfgCommon()->codeOrigins;
500     }
501     
502     // Having code origins implies that there has been some inlining.
503     bool hasCodeOrigins()
504     {
505         return JITCode::isOptimizingJIT(jitType());
506     }
507         
508     bool canGetCodeOrigin(CallSiteIndex index)
509     {
510         if (!hasCodeOrigins())
511             return false;
512         return index.bits() < codeOrigins().size();
513     }
514
515     CodeOrigin codeOrigin(CallSiteIndex index)
516     {
517         return codeOrigins()[index.bits()];
518     }
519
520     bool addFrequentExitSite(const DFG::FrequentExitSite& site)
521     {
522         ASSERT(JITCode::isBaselineCode(jitType()));
523         ConcurrentJITLocker locker(m_lock);
524         return m_exitProfile.add(locker, site);
525     }
526
527     bool hasExitSite(const ConcurrentJITLocker& locker, const DFG::FrequentExitSite& site) const
528     {
529         return m_exitProfile.hasExitSite(locker, site);
530     }
531     bool hasExitSite(const DFG::FrequentExitSite& site) const
532     {
533         ConcurrentJITLocker locker(m_lock);
534         return hasExitSite(locker, site);
535     }
536
537     DFG::ExitProfile& exitProfile() { return m_exitProfile; }
538
539     CompressedLazyOperandValueProfileHolder& lazyOperandValueProfiles()
540     {
541         return m_lazyOperandValueProfiles;
542     }
543 #endif // ENABLE(DFG_JIT)
544
545     // Constant Pool
546 #if ENABLE(DFG_JIT)
547     size_t numberOfIdentifiers() const { return m_unlinkedCode->numberOfIdentifiers() + numberOfDFGIdentifiers(); }
548     size_t numberOfDFGIdentifiers() const
549     {
550         if (!JITCode::isOptimizingJIT(jitType()))
551             return 0;
552
553         return m_jitCode->dfgCommon()->dfgIdentifiers.size();
554     }
555
556     const Identifier& identifier(int index) const
557     {
558         size_t unlinkedIdentifiers = m_unlinkedCode->numberOfIdentifiers();
559         if (static_cast<unsigned>(index) < unlinkedIdentifiers)
560             return m_unlinkedCode->identifier(index);
561         ASSERT(JITCode::isOptimizingJIT(jitType()));
562         return m_jitCode->dfgCommon()->dfgIdentifiers[index - unlinkedIdentifiers];
563     }
564 #else
565     size_t numberOfIdentifiers() const { return m_unlinkedCode->numberOfIdentifiers(); }
566     const Identifier& identifier(int index) const { return m_unlinkedCode->identifier(index); }
567 #endif
568
569     Vector<WriteBarrier<Unknown>>& constants() { return m_constantRegisters; }
570     Vector<SourceCodeRepresentation>& constantsSourceCodeRepresentation() { return m_constantsSourceCodeRepresentation; }
571     unsigned addConstant(JSValue v)
572     {
573         unsigned result = m_constantRegisters.size();
574         m_constantRegisters.append(WriteBarrier<Unknown>());
575         m_constantRegisters.last().set(m_globalObject->vm(), m_ownerExecutable.get(), v);
576         m_constantsSourceCodeRepresentation.append(SourceCodeRepresentation::Other);
577         return result;
578     }
579
580     unsigned addConstantLazily()
581     {
582         unsigned result = m_constantRegisters.size();
583         m_constantRegisters.append(WriteBarrier<Unknown>());
584         m_constantsSourceCodeRepresentation.append(SourceCodeRepresentation::Other);
585         return result;
586     }
587
588     WriteBarrier<Unknown>& constantRegister(int index) { return m_constantRegisters[index - FirstConstantRegisterIndex]; }
589     ALWAYS_INLINE bool isConstantRegisterIndex(int index) const { return index >= FirstConstantRegisterIndex; }
590     ALWAYS_INLINE JSValue getConstant(int index) const { return m_constantRegisters[index - FirstConstantRegisterIndex].get(); }
591     ALWAYS_INLINE SourceCodeRepresentation constantSourceCodeRepresentation(int index) const { return m_constantsSourceCodeRepresentation[index - FirstConstantRegisterIndex]; }
592
593     FunctionExecutable* functionDecl(int index) { return m_functionDecls[index].get(); }
594     int numberOfFunctionDecls() { return m_functionDecls.size(); }
595     FunctionExecutable* functionExpr(int index) { return m_functionExprs[index].get(); }
596     
597     RegExp* regexp(int index) const { return m_unlinkedCode->regexp(index); }
598
599     unsigned numberOfConstantBuffers() const
600     {
601         if (!m_rareData)
602             return 0;
603         return m_rareData->m_constantBuffers.size();
604     }
605     unsigned addConstantBuffer(const Vector<JSValue>& buffer)
606     {
607         createRareDataIfNecessary();
608         unsigned size = m_rareData->m_constantBuffers.size();
609         m_rareData->m_constantBuffers.append(buffer);
610         return size;
611     }
612
613     Vector<JSValue>& constantBufferAsVector(unsigned index)
614     {
615         ASSERT(m_rareData);
616         return m_rareData->m_constantBuffers[index];
617     }
618     JSValue* constantBuffer(unsigned index)
619     {
620         return constantBufferAsVector(index).data();
621     }
622
623     Heap* heap() const { return m_heap; }
624     JSGlobalObject* globalObject() { return m_globalObject.get(); }
625
626     JSGlobalObject* globalObjectFor(CodeOrigin);
627
628     BytecodeLivenessAnalysis& livenessAnalysis()
629     {
630         {
631             ConcurrentJITLocker locker(m_lock);
632             if (!!m_livenessAnalysis)
633                 return *m_livenessAnalysis;
634         }
635         std::unique_ptr<BytecodeLivenessAnalysis> analysis =
636             std::make_unique<BytecodeLivenessAnalysis>(this);
637         {
638             ConcurrentJITLocker locker(m_lock);
639             if (!m_livenessAnalysis)
640                 m_livenessAnalysis = WTF::move(analysis);
641             return *m_livenessAnalysis;
642         }
643     }
644     
645     void validate();
646
647     // Jump Tables
648
649     size_t numberOfSwitchJumpTables() const { return m_rareData ? m_rareData->m_switchJumpTables.size() : 0; }
650     SimpleJumpTable& addSwitchJumpTable() { createRareDataIfNecessary(); m_rareData->m_switchJumpTables.append(SimpleJumpTable()); return m_rareData->m_switchJumpTables.last(); }
651     SimpleJumpTable& switchJumpTable(int tableIndex) { RELEASE_ASSERT(m_rareData); return m_rareData->m_switchJumpTables[tableIndex]; }
652     void clearSwitchJumpTables()
653     {
654         if (!m_rareData)
655             return;
656         m_rareData->m_switchJumpTables.clear();
657     }
658
659     size_t numberOfStringSwitchJumpTables() const { return m_rareData ? m_rareData->m_stringSwitchJumpTables.size() : 0; }
660     StringJumpTable& addStringSwitchJumpTable() { createRareDataIfNecessary(); m_rareData->m_stringSwitchJumpTables.append(StringJumpTable()); return m_rareData->m_stringSwitchJumpTables.last(); }
661     StringJumpTable& stringSwitchJumpTable(int tableIndex) { RELEASE_ASSERT(m_rareData); return m_rareData->m_stringSwitchJumpTables[tableIndex]; }
662
663     EvalCodeCache& evalCodeCache() { createRareDataIfNecessary(); return m_rareData->m_evalCodeCache; }
664
665     enum ShrinkMode {
666         // Shrink prior to generating machine code that may point directly into vectors.
667         EarlyShrink,
668
669         // Shrink after generating machine code, and after possibly creating new vectors
670         // and appending to others. At this time it is not safe to shrink certain vectors
671         // because we would have generated machine code that references them directly.
672         LateShrink
673     };
674     void shrinkToFit(ShrinkMode);
675
676     // Functions for controlling when JITting kicks in, in a mixed mode
677     // execution world.
678
679     bool checkIfJITThresholdReached()
680     {
681         return m_llintExecuteCounter.checkIfThresholdCrossedAndSet(this);
682     }
683
684     void dontJITAnytimeSoon()
685     {
686         m_llintExecuteCounter.deferIndefinitely();
687     }
688
689     void jitAfterWarmUp()
690     {
691         m_llintExecuteCounter.setNewThreshold(Options::thresholdForJITAfterWarmUp(), this);
692     }
693
694     void jitSoon()
695     {
696         m_llintExecuteCounter.setNewThreshold(Options::thresholdForJITSoon(), this);
697     }
698
699     const BaselineExecutionCounter& llintExecuteCounter() const
700     {
701         return m_llintExecuteCounter;
702     }
703
704     // Functions for controlling when tiered compilation kicks in. This
705     // controls both when the optimizing compiler is invoked and when OSR
706     // entry happens. Two triggers exist: the loop trigger and the return
707     // trigger. In either case, when an addition to m_jitExecuteCounter
708     // causes it to become non-negative, the optimizing compiler is
709     // invoked. This includes a fast check to see if this CodeBlock has
710     // already been optimized (i.e. replacement() returns a CodeBlock
711     // that was optimized with a higher tier JIT than this one). In the
712     // case of the loop trigger, if the optimized compilation succeeds
713     // (or has already succeeded in the past) then OSR is attempted to
714     // redirect program flow into the optimized code.
715
716     // These functions are called from within the optimization triggers,
717     // and are used as a single point at which we define the heuristics
718     // for how much warm-up is mandated before the next optimization
719     // trigger files. All CodeBlocks start out with optimizeAfterWarmUp(),
720     // as this is called from the CodeBlock constructor.
721
722     // When we observe a lot of speculation failures, we trigger a
723     // reoptimization. But each time, we increase the optimization trigger
724     // to avoid thrashing.
725     JS_EXPORT_PRIVATE unsigned reoptimizationRetryCounter() const;
726     void countReoptimization();
727 #if ENABLE(JIT)
728     static unsigned numberOfLLIntBaselineCalleeSaveRegisters() { return RegisterSet::llintBaselineCalleeSaveRegisters().numberOfSetRegisters(); }
729     static size_t llintBaselineCalleeSaveSpaceAsVirtualRegisters();
730     size_t calleeSaveSpaceAsVirtualRegisters();
731
732     unsigned numberOfDFGCompiles();
733
734     int32_t codeTypeThresholdMultiplier() const;
735
736     int32_t adjustedCounterValue(int32_t desiredThreshold);
737
738     int32_t* addressOfJITExecuteCounter()
739     {
740         return &m_jitExecuteCounter.m_counter;
741     }
742
743     static ptrdiff_t offsetOfJITExecuteCounter() { return OBJECT_OFFSETOF(CodeBlock, m_jitExecuteCounter) + OBJECT_OFFSETOF(BaselineExecutionCounter, m_counter); }
744     static ptrdiff_t offsetOfJITExecutionActiveThreshold() { return OBJECT_OFFSETOF(CodeBlock, m_jitExecuteCounter) + OBJECT_OFFSETOF(BaselineExecutionCounter, m_activeThreshold); }
745     static ptrdiff_t offsetOfJITExecutionTotalCount() { return OBJECT_OFFSETOF(CodeBlock, m_jitExecuteCounter) + OBJECT_OFFSETOF(BaselineExecutionCounter, m_totalCount); }
746
747     const BaselineExecutionCounter& jitExecuteCounter() const { return m_jitExecuteCounter; }
748
749     unsigned optimizationDelayCounter() const { return m_optimizationDelayCounter; }
750
751     // Check if the optimization threshold has been reached, and if not,
752     // adjust the heuristics accordingly. Returns true if the threshold has
753     // been reached.
754     bool checkIfOptimizationThresholdReached();
755
756     // Call this to force the next optimization trigger to fire. This is
757     // rarely wise, since optimization triggers are typically more
758     // expensive than executing baseline code.
759     void optimizeNextInvocation();
760
761     // Call this to prevent optimization from happening again. Note that
762     // optimization will still happen after roughly 2^29 invocations,
763     // so this is really meant to delay that as much as possible. This
764     // is called if optimization failed, and we expect it to fail in
765     // the future as well.
766     void dontOptimizeAnytimeSoon();
767
768     // Call this to reinitialize the counter to its starting state,
769     // forcing a warm-up to happen before the next optimization trigger
770     // fires. This is called in the CodeBlock constructor. It also
771     // makes sense to call this if an OSR exit occurred. Note that
772     // OSR exit code is code generated, so the value of the execute
773     // counter that this corresponds to is also available directly.
774     void optimizeAfterWarmUp();
775
776     // Call this to force an optimization trigger to fire only after
777     // a lot of warm-up.
778     void optimizeAfterLongWarmUp();
779
780     // Call this to cause an optimization trigger to fire soon, but
781     // not necessarily the next one. This makes sense if optimization
782     // succeeds. Successfuly optimization means that all calls are
783     // relinked to the optimized code, so this only affects call
784     // frames that are still executing this CodeBlock. The value here
785     // is tuned to strike a balance between the cost of OSR entry
786     // (which is too high to warrant making every loop back edge to
787     // trigger OSR immediately) and the cost of executing baseline
788     // code (which is high enough that we don't necessarily want to
789     // have a full warm-up). The intuition for calling this instead of
790     // optimizeNextInvocation() is for the case of recursive functions
791     // with loops. Consider that there may be N call frames of some
792     // recursive function, for a reasonably large value of N. The top
793     // one triggers optimization, and then returns, and then all of
794     // the others return. We don't want optimization to be triggered on
795     // each return, as that would be superfluous. It only makes sense
796     // to trigger optimization if one of those functions becomes hot
797     // in the baseline code.
798     void optimizeSoon();
799
800     void forceOptimizationSlowPathConcurrently();
801
802     void setOptimizationThresholdBasedOnCompilationResult(CompilationResult);
803     
804     uint32_t osrExitCounter() const { return m_osrExitCounter; }
805
806     void countOSRExit() { m_osrExitCounter++; }
807
808     uint32_t* addressOfOSRExitCounter() { return &m_osrExitCounter; }
809
810     static ptrdiff_t offsetOfOSRExitCounter() { return OBJECT_OFFSETOF(CodeBlock, m_osrExitCounter); }
811
812     uint32_t adjustedExitCountThreshold(uint32_t desiredThreshold);
813     uint32_t exitCountThresholdForReoptimization();
814     uint32_t exitCountThresholdForReoptimizationFromLoop();
815     bool shouldReoptimizeNow();
816     bool shouldReoptimizeFromLoopNow();
817
818     void setCalleeSaveRegisters(RegisterSet);
819     void setCalleeSaveRegisters(std::unique_ptr<RegisterAtOffsetList>);
820     
821     RegisterAtOffsetList* calleeSaveRegisters() const { return m_calleeSaveRegisters.get(); }
822 #else // No JIT
823     static unsigned numberOfLLIntBaselineCalleeSaveRegisters() { return 0; }
824     static size_t llintBaselineCalleeSaveSpaceAsVirtualRegisters() { return 0; };
825     void optimizeAfterWarmUp() { }
826     unsigned numberOfDFGCompiles() { return 0; }
827 #endif
828
829     bool shouldOptimizeNow();
830     void updateAllValueProfilePredictions();
831     void updateAllArrayPredictions();
832     void updateAllPredictions();
833
834     unsigned frameRegisterCount();
835     int stackPointerOffset();
836
837     bool hasOpDebugForLineAndColumn(unsigned line, unsigned column);
838
839     bool hasDebuggerRequests() const { return m_debuggerRequests; }
840     void* debuggerRequestsAddress() { return &m_debuggerRequests; }
841
842     void addBreakpoint(unsigned numBreakpoints);
843     void removeBreakpoint(unsigned numBreakpoints)
844     {
845         ASSERT(m_numBreakpoints >= numBreakpoints);
846         m_numBreakpoints -= numBreakpoints;
847     }
848
849     enum SteppingMode {
850         SteppingModeDisabled,
851         SteppingModeEnabled
852     };
853     void setSteppingMode(SteppingMode);
854
855     void clearDebuggerRequests()
856     {
857         m_steppingMode = SteppingModeDisabled;
858         m_numBreakpoints = 0;
859     }
860     
861     // FIXME: Make these remaining members private.
862
863     int m_numLocalRegistersForCalleeSaves;
864     int m_numCalleeRegisters;
865     int m_numVars;
866     bool m_isConstructor : 1;
867     
868     // This is intentionally public; it's the responsibility of anyone doing any
869     // of the following to hold the lock:
870     //
871     // - Modifying any inline cache in this code block.
872     //
873     // - Quering any inline cache in this code block, from a thread other than
874     //   the main thread.
875     //
876     // Additionally, it's only legal to modify the inline cache on the main
877     // thread. This means that the main thread can query the inline cache without
878     // locking. This is crucial since executing the inline cache is effectively
879     // "querying" it.
880     //
881     // Another exception to the rules is that the GC can do whatever it wants
882     // without holding any locks, because the GC is guaranteed to wait until any
883     // concurrent compilation threads finish what they're doing.
884     mutable ConcurrentJITLock m_lock;
885     
886     bool m_shouldAlwaysBeInlined; // Not a bitfield because the JIT wants to store to it.
887     bool m_allTransitionsHaveBeenMarked : 1; // Initialized and used on every GC.
888     
889     bool m_didFailFTLCompilation : 1;
890     bool m_hasBeenCompiledWithFTL : 1;
891
892     // Internal methods for use by validation code. It would be private if it wasn't
893     // for the fact that we use it from anonymous namespaces.
894     void beginValidationDidFail();
895     NO_RETURN_DUE_TO_CRASH void endValidationDidFail();
896
897     bool isKnownToBeLiveDuringGC(); // Will only return valid results when called during GC. Assumes that you've already established that the owner executable is live.
898
899     struct RareData {
900         WTF_MAKE_FAST_ALLOCATED;
901     public:
902         Vector<HandlerInfo> m_exceptionHandlers;
903
904         // Buffers used for large array literals
905         Vector<Vector<JSValue>> m_constantBuffers;
906
907         // Jump Tables
908         Vector<SimpleJumpTable> m_switchJumpTables;
909         Vector<StringJumpTable> m_stringSwitchJumpTables;
910
911         EvalCodeCache m_evalCodeCache;
912     };
913
914     void clearExceptionHandlers()
915     {
916         if (m_rareData)
917             m_rareData->m_exceptionHandlers.clear();
918     }
919
920     void appendExceptionHandler(const HandlerInfo& handler)
921     {
922         createRareDataIfNecessary(); // We may be handling the exception of an inlined call frame.
923         m_rareData->m_exceptionHandlers.append(handler);
924     }
925
926 protected:
927     virtual void visitWeakReferences(SlotVisitor&) override;
928     virtual void finalizeUnconditionally() override;
929     void finalizeLLIntInlineCaches();
930     void finalizeBaselineJITInlineCaches();
931
932 #if ENABLE(DFG_JIT)
933     void tallyFrequentExitSites();
934 #else
935     void tallyFrequentExitSites() { }
936 #endif
937
938 private:
939     friend class CodeBlockSet;
940     
941     CodeBlock* specialOSREntryBlockOrNull();
942     
943     void noticeIncomingCall(ExecState* callerFrame);
944     
945     double optimizationThresholdScalingFactor();
946
947     void updateAllPredictionsAndCountLiveness(unsigned& numberOfLiveNonArgumentValueProfiles, unsigned& numberOfSamplesInProfiles);
948
949     void setConstantRegisters(const Vector<WriteBarrier<Unknown>>& constants, const Vector<SourceCodeRepresentation>& constantsSourceCodeRepresentation)
950     {
951         ASSERT(constants.size() == constantsSourceCodeRepresentation.size());
952         size_t count = constants.size();
953         m_constantRegisters.resizeToFit(count);
954         for (size_t i = 0; i < count; i++)
955             m_constantRegisters[i].set(*m_vm, ownerExecutable(), constants[i].get());
956         m_constantsSourceCodeRepresentation = constantsSourceCodeRepresentation;
957     }
958
959     void replaceConstant(int index, JSValue value)
960     {
961         ASSERT(isConstantRegisterIndex(index) && static_cast<size_t>(index - FirstConstantRegisterIndex) < m_constantRegisters.size());
962         m_constantRegisters[index - FirstConstantRegisterIndex].set(m_globalObject->vm(), m_ownerExecutable.get(), value);
963     }
964
965     void dumpBytecode(
966         PrintStream&, ExecState*, const Instruction* begin, const Instruction*&,
967         const StubInfoMap& = StubInfoMap(), const CallLinkInfoMap& = CallLinkInfoMap());
968
969     CString registerName(int r) const;
970     CString constantName(int index) const;
971     void printUnaryOp(PrintStream&, ExecState*, int location, const Instruction*&, const char* op);
972     void printBinaryOp(PrintStream&, ExecState*, int location, const Instruction*&, const char* op);
973     void printConditionalJump(PrintStream&, ExecState*, const Instruction*, const Instruction*&, int location, const char* op);
974     void printGetByIdOp(PrintStream&, ExecState*, int location, const Instruction*&);
975     void printGetByIdCacheStatus(PrintStream&, ExecState*, int location, const StubInfoMap&);
976     enum CacheDumpMode { DumpCaches, DontDumpCaches };
977     void printCallOp(PrintStream&, ExecState*, int location, const Instruction*&, const char* op, CacheDumpMode, bool& hasPrintedProfiling, const CallLinkInfoMap&);
978     void printPutByIdOp(PrintStream&, ExecState*, int location, const Instruction*&, const char* op);
979     void printPutByIdCacheStatus(PrintStream&, int location, const StubInfoMap&);
980     void printLocationAndOp(PrintStream&, ExecState*, int location, const Instruction*&, const char* op);
981     void printLocationOpAndRegisterOperand(PrintStream&, ExecState*, int location, const Instruction*& it, const char* op, int operand);
982
983     void beginDumpProfiling(PrintStream&, bool& hasPrintedProfiling);
984     void dumpValueProfiling(PrintStream&, const Instruction*&, bool& hasPrintedProfiling);
985     void dumpArrayProfiling(PrintStream&, const Instruction*&, bool& hasPrintedProfiling);
986     void dumpRareCaseProfile(PrintStream&, const char* name, RareCaseProfile*, bool& hasPrintedProfiling);
987         
988     bool shouldVisitStrongly();
989     bool shouldJettisonDueToWeakReference();
990     bool shouldJettisonDueToOldAge();
991     
992     void propagateTransitions(SlotVisitor&);
993     void determineLiveness(SlotVisitor&);
994         
995     void stronglyVisitStrongReferences(SlotVisitor&);
996     void stronglyVisitWeakReferences(SlotVisitor&);
997     void visitOSRExitTargets(SlotVisitor&);
998
999     std::chrono::milliseconds timeSinceCreation()
1000     {
1001         return std::chrono::duration_cast<std::chrono::milliseconds>(
1002             std::chrono::steady_clock::now() - m_creationTime);
1003     }
1004
1005     void createRareDataIfNecessary()
1006     {
1007         if (!m_rareData)
1008             m_rareData = std::make_unique<RareData>();
1009     }
1010
1011     void insertBasicBlockBoundariesForControlFlowProfiler(Vector<Instruction, 0, UnsafeVectorOverflow>&);
1012
1013     WriteBarrier<UnlinkedCodeBlock> m_unlinkedCode;
1014     int m_numParameters;
1015     union {
1016         unsigned m_debuggerRequests;
1017         struct {
1018             unsigned m_hasDebuggerStatement : 1;
1019             unsigned m_steppingMode : 1;
1020             unsigned m_numBreakpoints : 30;
1021         };
1022     };
1023     WriteBarrier<ExecutableBase> m_ownerExecutable;
1024     VM* m_vm;
1025
1026     RefCountedArray<Instruction> m_instructions;
1027     VirtualRegister m_thisRegister;
1028     VirtualRegister m_scopeRegister;
1029     VirtualRegister m_lexicalEnvironmentRegister;
1030
1031     bool m_isStrictMode;
1032     bool m_needsActivation;
1033
1034     Atomic<bool> m_visitAggregateHasBeenCalled;
1035     Atomic<bool> m_visitStronglyHasBeenCalled;
1036
1037     RefPtr<SourceProvider> m_source;
1038     unsigned m_sourceOffset;
1039     unsigned m_firstLineColumnOffset;
1040     CodeType m_codeType;
1041
1042     Vector<LLIntCallLinkInfo> m_llintCallLinkInfos;
1043     SentinelLinkedList<LLIntCallLinkInfo, BasicRawSentinelNode<LLIntCallLinkInfo>> m_incomingLLIntCalls;
1044     RefPtr<JITCode> m_jitCode;
1045 #if ENABLE(JIT)
1046     std::unique_ptr<RegisterAtOffsetList> m_calleeSaveRegisters;
1047     Bag<StructureStubInfo> m_stubInfos;
1048     Bag<ByValInfo> m_byValInfos;
1049     Bag<CallLinkInfo> m_callLinkInfos;
1050     SentinelLinkedList<CallLinkInfo, BasicRawSentinelNode<CallLinkInfo>> m_incomingCalls;
1051     SentinelLinkedList<PolymorphicCallNode, BasicRawSentinelNode<PolymorphicCallNode>> m_incomingPolymorphicCalls;
1052 #endif
1053     std::unique_ptr<CompactJITCodeMap> m_jitCodeMap;
1054 #if ENABLE(DFG_JIT)
1055     // This is relevant to non-DFG code blocks that serve as the profiled code block
1056     // for DFG code blocks.
1057     DFG::ExitProfile m_exitProfile;
1058     CompressedLazyOperandValueProfileHolder m_lazyOperandValueProfiles;
1059 #endif
1060     Vector<ValueProfile> m_argumentValueProfiles;
1061     Vector<ValueProfile> m_valueProfiles;
1062     SegmentedVector<RareCaseProfile, 8> m_rareCaseProfiles;
1063     SegmentedVector<RareCaseProfile, 8> m_specialFastCaseProfiles;
1064     Vector<ArrayAllocationProfile> m_arrayAllocationProfiles;
1065     ArrayProfileVector m_arrayProfiles;
1066     Vector<ObjectAllocationProfile> m_objectAllocationProfiles;
1067
1068     // Constant Pool
1069     COMPILE_ASSERT(sizeof(Register) == sizeof(WriteBarrier<Unknown>), Register_must_be_same_size_as_WriteBarrier_Unknown);
1070     // TODO: This could just be a pointer to m_unlinkedCodeBlock's data, but the DFG mutates
1071     // it, so we're stuck with it for now.
1072     Vector<WriteBarrier<Unknown>> m_constantRegisters;
1073     Vector<SourceCodeRepresentation> m_constantsSourceCodeRepresentation;
1074     Vector<WriteBarrier<FunctionExecutable>> m_functionDecls;
1075     Vector<WriteBarrier<FunctionExecutable>> m_functionExprs;
1076
1077     RefPtr<CodeBlock> m_alternative;
1078     
1079     BaselineExecutionCounter m_llintExecuteCounter;
1080
1081     BaselineExecutionCounter m_jitExecuteCounter;
1082     int32_t m_totalJITExecutions;
1083     uint32_t m_osrExitCounter;
1084     uint16_t m_optimizationDelayCounter;
1085     uint16_t m_reoptimizationRetryCounter;
1086
1087     std::chrono::steady_clock::time_point m_creationTime;
1088
1089     mutable CodeBlockHash m_hash;
1090
1091     std::unique_ptr<BytecodeLivenessAnalysis> m_livenessAnalysis;
1092
1093     std::unique_ptr<RareData> m_rareData;
1094 #if ENABLE(JIT)
1095     DFG::CapabilityLevel m_capabilityLevelState;
1096 #endif
1097 };
1098
1099 // Program code is not marked by any function, so we make the global object
1100 // responsible for marking it.
1101
1102 class GlobalCodeBlock : public CodeBlock {
1103 protected:
1104     GlobalCodeBlock(CopyParsedBlockTag, GlobalCodeBlock& other)
1105     : CodeBlock(CopyParsedBlock, other)
1106     {
1107     }
1108         
1109     GlobalCodeBlock(ScriptExecutable* ownerExecutable, UnlinkedCodeBlock* unlinkedCodeBlock, JSScope* scope, PassRefPtr<SourceProvider> sourceProvider, unsigned sourceOffset, unsigned firstLineColumnOffset)
1110         : CodeBlock(ownerExecutable, unlinkedCodeBlock, scope, sourceProvider, sourceOffset, firstLineColumnOffset)
1111     {
1112     }
1113 };
1114
1115 class ProgramCodeBlock : public GlobalCodeBlock {
1116 public:
1117     ProgramCodeBlock(CopyParsedBlockTag, ProgramCodeBlock& other)
1118     : GlobalCodeBlock(CopyParsedBlock, other)
1119     {
1120     }
1121
1122     ProgramCodeBlock(ProgramExecutable* ownerExecutable, UnlinkedProgramCodeBlock* unlinkedCodeBlock, JSScope* scope, PassRefPtr<SourceProvider> sourceProvider, unsigned firstLineColumnOffset)
1123         : GlobalCodeBlock(ownerExecutable, unlinkedCodeBlock, scope, sourceProvider, 0, firstLineColumnOffset)
1124     {
1125     }
1126
1127 #if ENABLE(JIT)
1128 protected:
1129     virtual CodeBlock* replacement() override;
1130     virtual DFG::CapabilityLevel capabilityLevelInternal() override;
1131 #endif
1132 };
1133
1134 class ModuleProgramCodeBlock : public GlobalCodeBlock {
1135 public:
1136     ModuleProgramCodeBlock(CopyParsedBlockTag, ModuleProgramCodeBlock& other)
1137         : GlobalCodeBlock(CopyParsedBlock, other)
1138     {
1139     }
1140
1141     ModuleProgramCodeBlock(ModuleProgramExecutable* ownerExecutable, UnlinkedModuleProgramCodeBlock* unlinkedCodeBlock, JSScope* scope, PassRefPtr<SourceProvider> sourceProvider, unsigned firstLineColumnOffset)
1142         : GlobalCodeBlock(ownerExecutable, unlinkedCodeBlock, scope, sourceProvider, 0, firstLineColumnOffset)
1143     {
1144     }
1145
1146 #if ENABLE(JIT)
1147 protected:
1148     virtual CodeBlock* replacement() override;
1149     virtual DFG::CapabilityLevel capabilityLevelInternal() override;
1150 #endif
1151 };
1152
1153 class EvalCodeBlock : public GlobalCodeBlock {
1154 public:
1155     EvalCodeBlock(CopyParsedBlockTag, EvalCodeBlock& other)
1156         : GlobalCodeBlock(CopyParsedBlock, other)
1157     {
1158     }
1159         
1160     EvalCodeBlock(EvalExecutable* ownerExecutable, UnlinkedEvalCodeBlock* unlinkedCodeBlock, JSScope* scope, PassRefPtr<SourceProvider> sourceProvider)
1161         : GlobalCodeBlock(ownerExecutable, unlinkedCodeBlock, scope, sourceProvider, 0, 1)
1162     {
1163     }
1164     
1165     const Identifier& variable(unsigned index) { return unlinkedEvalCodeBlock()->variable(index); }
1166     unsigned numVariables() { return unlinkedEvalCodeBlock()->numVariables(); }
1167     
1168 #if ENABLE(JIT)
1169 protected:
1170     virtual CodeBlock* replacement() override;
1171     virtual DFG::CapabilityLevel capabilityLevelInternal() override;
1172 #endif
1173     
1174 private:
1175     UnlinkedEvalCodeBlock* unlinkedEvalCodeBlock() const { return jsCast<UnlinkedEvalCodeBlock*>(unlinkedCodeBlock()); }
1176 };
1177
1178 class FunctionCodeBlock : public CodeBlock {
1179 public:
1180     FunctionCodeBlock(CopyParsedBlockTag, FunctionCodeBlock& other)
1181         : CodeBlock(CopyParsedBlock, other)
1182     {
1183     }
1184
1185     FunctionCodeBlock(FunctionExecutable* ownerExecutable, UnlinkedFunctionCodeBlock* unlinkedCodeBlock, JSScope* scope, PassRefPtr<SourceProvider> sourceProvider, unsigned sourceOffset, unsigned firstLineColumnOffset)
1186         : CodeBlock(ownerExecutable, unlinkedCodeBlock, scope, sourceProvider, sourceOffset, firstLineColumnOffset)
1187     {
1188     }
1189     
1190 #if ENABLE(JIT)
1191 protected:
1192     virtual CodeBlock* replacement() override;
1193     virtual DFG::CapabilityLevel capabilityLevelInternal() override;
1194 #endif
1195 };
1196
1197 #if ENABLE(WEBASSEMBLY)
1198 class WebAssemblyCodeBlock : public CodeBlock {
1199 public:
1200     WebAssemblyCodeBlock(CopyParsedBlockTag, WebAssemblyCodeBlock& other)
1201         : CodeBlock(CopyParsedBlock, other)
1202     {
1203     }
1204
1205     WebAssemblyCodeBlock(WebAssemblyExecutable* ownerExecutable, VM& vm, JSGlobalObject* globalObject)
1206         : CodeBlock(ownerExecutable, vm, globalObject)
1207     {
1208     }
1209
1210 #if ENABLE(JIT)
1211 protected:
1212     virtual CodeBlock* replacement() override;
1213     virtual DFG::CapabilityLevel capabilityLevelInternal() override;
1214 #endif
1215 };
1216 #endif
1217
1218 inline Register& ExecState::r(int index)
1219 {
1220     CodeBlock* codeBlock = this->codeBlock();
1221     if (codeBlock->isConstantRegisterIndex(index))
1222         return *reinterpret_cast<Register*>(&codeBlock->constantRegister(index));
1223     return this[index];
1224 }
1225
1226 inline Register& ExecState::r(VirtualRegister reg)
1227 {
1228     return r(reg.offset());
1229 }
1230
1231 inline Register& ExecState::uncheckedR(int index)
1232 {
1233     RELEASE_ASSERT(index < FirstConstantRegisterIndex);
1234     return this[index];
1235 }
1236
1237 inline Register& ExecState::uncheckedR(VirtualRegister reg)
1238 {
1239     return uncheckedR(reg.offset());
1240 }
1241
1242 inline void CodeBlock::clearMarks()
1243 {
1244     m_visitStronglyHasBeenCalled.store(false, std::memory_order_relaxed);
1245     m_visitAggregateHasBeenCalled.store(false, std::memory_order_relaxed);
1246 }
1247
1248 inline void CodeBlockSet::mark(void* candidateCodeBlock)
1249 {
1250     // We have to check for 0 and -1 because those are used by the HashMap as markers.
1251     uintptr_t value = reinterpret_cast<uintptr_t>(candidateCodeBlock);
1252     
1253     // This checks for both of those nasty cases in one go.
1254     // 0 + 1 = 1
1255     // -1 + 1 = 0
1256     if (value + 1 <= 1)
1257         return;
1258
1259     CodeBlock* codeBlock = static_cast<CodeBlock*>(candidateCodeBlock); 
1260     if (!m_oldCodeBlocks.contains(codeBlock) && !m_newCodeBlocks.contains(codeBlock))
1261         return;
1262
1263     mark(codeBlock);
1264 }
1265
1266 inline void CodeBlockSet::mark(CodeBlock* codeBlock)
1267 {
1268     if (!codeBlock)
1269         return;
1270     
1271     // Force GC to visit all CodeBlocks on the stack, including old CodeBlocks
1272     // that have not executed a barrier. This is overkill, but we have always
1273     // done this, and it might help us recover gracefully if we forget to execute
1274     // a barrier when a CodeBlock needs it.
1275     codeBlock->clearMarks();
1276
1277 #if ENABLE(GGC)
1278     m_currentlyExecuting.add(codeBlock);
1279 #endif
1280 }
1281
1282 template <typename Functor> inline void ScriptExecutable::forEachCodeBlock(Functor&& functor)
1283 {
1284     switch (type()) {
1285     case ProgramExecutableType: {
1286         if (CodeBlock* codeBlock = jsCast<ProgramExecutable*>(this)->m_programCodeBlock.get())
1287             codeBlock->forEachRelatedCodeBlock(std::forward<Functor>(functor));
1288         break;
1289     }
1290
1291     case EvalExecutableType: {
1292         if (CodeBlock* codeBlock = jsCast<EvalExecutable*>(this)->m_evalCodeBlock.get())
1293             codeBlock->forEachRelatedCodeBlock(std::forward<Functor>(functor));
1294         break;
1295     }
1296
1297     case FunctionExecutableType: {
1298         Functor f(std::forward<Functor>(functor));
1299         FunctionExecutable* executable = jsCast<FunctionExecutable*>(this);
1300         if (CodeBlock* codeBlock = executable->m_codeBlockForCall.get())
1301             codeBlock->forEachRelatedCodeBlock(f);
1302         if (CodeBlock* codeBlock = executable->m_codeBlockForConstruct.get())
1303             codeBlock->forEachRelatedCodeBlock(f);
1304         break;
1305     }
1306
1307     case ModuleProgramExecutableType: {
1308         if (CodeBlock* codeBlock = jsCast<ModuleProgramExecutable*>(this)->m_moduleProgramCodeBlock.get())
1309             codeBlock->forEachRelatedCodeBlock(std::forward<Functor>(functor));
1310         break;
1311     }
1312
1313     default:
1314         RELEASE_ASSERT_NOT_REACHED();
1315     }
1316 }
1317
1318 } // namespace JSC
1319
1320 #endif // CodeBlock_h