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