2015-10-01 Geoffrey Garen <ggaren@apple.com>
[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 "DFGExitProfile.h"
47 #include "DeferredCompilationCallback.h"
48 #include "EvalCodeCache.h"
49 #include "ExecutionCounter.h"
50 #include "ExpressionRangeInfo.h"
51 #include "HandlerInfo.h"
52 #include "ObjectAllocationProfile.h"
53 #include "Options.h"
54 #include "PutPropertySlot.h"
55 #include "Instruction.h"
56 #include "JITCode.h"
57 #include "JITWriteBarrier.h"
58 #include "JSGlobalObject.h"
59 #include "JumpTable.h"
60 #include "LLIntCallLinkInfo.h"
61 #include "LazyOperandValueProfile.h"
62 #include "ProfilerCompilation.h"
63 #include "ProfilerJettisonReason.h"
64 #include "RegExpObject.h"
65 #include "StructureStubInfo.h"
66 #include "UnconditionalFinalizer.h"
67 #include "ValueProfile.h"
68 #include "VirtualRegister.h"
69 #include "Watchpoint.h"
70 #include <wtf/Bag.h>
71 #include <wtf/FastMalloc.h>
72 #include <wtf/RefCountedArray.h>
73 #include <wtf/RefPtr.h>
74 #include <wtf/SegmentedVector.h>
75 #include <wtf/Vector.h>
76 #include <wtf/text/WTFString.h>
77
78 namespace JSC {
79
80 class ExecState;
81 class LLIntOffsetsExtractor;
82 class RegisterAtOffsetList;
83 class TypeLocation;
84 class JSModuleEnvironment;
85
86 enum ReoptimizationMode { DontCountReoptimization, CountReoptimization };
87
88 class CodeBlock : public ThreadSafeRefCounted<CodeBlock>, public UnconditionalFinalizer, public WeakReferenceHarvester {
89     WTF_MAKE_FAST_ALLOCATED;
90     friend class BytecodeLivenessAnalysis;
91     friend class JIT;
92     friend class LLIntOffsetsExtractor;
93 public:
94     enum CopyParsedBlockTag { CopyParsedBlock };
95 protected:
96     CodeBlock(CopyParsedBlockTag, CodeBlock& other);
97         
98     CodeBlock(ScriptExecutable* ownerExecutable, UnlinkedCodeBlock*, JSScope*, PassRefPtr<SourceProvider>, unsigned sourceOffset, unsigned firstLineColumnOffset);
99 #if ENABLE(WEBASSEMBLY)
100     CodeBlock(WebAssemblyExecutable* ownerExecutable, VM&, JSGlobalObject*);
101 #endif
102
103     WriteBarrier<JSGlobalObject> m_globalObject;
104     Heap* m_heap;
105
106 public:
107     JS_EXPORT_PRIVATE virtual ~CodeBlock();
108
109     UnlinkedCodeBlock* unlinkedCodeBlock() const { return m_unlinkedCode.get(); }
110
111     CString inferredName() const;
112     CodeBlockHash hash() const;
113     bool hasHash() const;
114     bool isSafeToComputeHash() const;
115     CString hashAsStringIfPossible() const;
116     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.
117     CString sourceCodeOnOneLine() const; // As sourceCodeForTools(), but replaces all whitespace runs with a single space.
118     void dumpAssumingJITType(PrintStream&, JITCode::JITType) const;
119     void dump(PrintStream&) const;
120
121     int numParameters() const { return m_numParameters; }
122     void setNumParameters(int newValue);
123
124     int* addressOfNumParameters() { return &m_numParameters; }
125     static ptrdiff_t offsetOfNumParameters() { return OBJECT_OFFSETOF(CodeBlock, m_numParameters); }
126
127     CodeBlock* alternative() { return m_alternative.get(); }
128     void setAlternative(PassRefPtr<CodeBlock> alternative) { m_alternative = alternative; }
129
130     template <typename Functor> void forEachRelatedCodeBlock(Functor&& functor)
131     {
132         Functor f(std::forward<Functor>(functor));
133         Vector<CodeBlock*, 4> codeBlocks;
134         codeBlocks.append(this);
135
136         while (!codeBlocks.isEmpty()) {
137             CodeBlock* currentCodeBlock = codeBlocks.takeLast();
138             f(currentCodeBlock);
139
140             if (CodeBlock* alternative = currentCodeBlock->alternative())
141                 codeBlocks.append(alternative);
142             if (CodeBlock* osrEntryBlock = currentCodeBlock->specialOSREntryBlockOrNull())
143                 codeBlocks.append(osrEntryBlock);
144         }
145     }
146     
147     CodeSpecializationKind specializationKind() const
148     {
149         return specializationFromIsConstruct(m_isConstructor);
150     }
151     
152     CodeBlock* baselineAlternative();
153     
154     // FIXME: Get rid of this.
155     // https://bugs.webkit.org/show_bug.cgi?id=123677
156     CodeBlock* baselineVersion();
157
158     void clearMarks();
159     void visitAggregate(SlotVisitor&);
160     void visitStrongly(SlotVisitor&);
161
162     void dumpSource();
163     void dumpSource(PrintStream&);
164
165     void dumpBytecode();
166     void dumpBytecode(PrintStream&);
167     void dumpBytecode(
168         PrintStream&, unsigned bytecodeOffset,
169         const StubInfoMap& = StubInfoMap(), const CallLinkInfoMap& = CallLinkInfoMap());
170     void printStructures(PrintStream&, const Instruction*);
171     void printStructure(PrintStream&, const char* name, const Instruction*, int operand);
172
173     bool isStrictMode() const { return m_isStrictMode; }
174     ECMAMode ecmaMode() const { return isStrictMode() ? StrictMode : NotStrictMode; }
175
176     inline bool isKnownNotImmediate(int index)
177     {
178         if (index == m_thisRegister.offset() && !m_isStrictMode)
179             return true;
180
181         if (isConstantRegisterIndex(index))
182             return getConstant(index).isCell();
183
184         return false;
185     }
186
187     ALWAYS_INLINE bool isTemporaryRegisterIndex(int index)
188     {
189         return index >= m_numVars;
190     }
191
192     enum class RequiredHandler {
193         CatchHandler,
194         AnyHandler
195     };
196     HandlerInfo* handlerForBytecodeOffset(unsigned bytecodeOffset, RequiredHandler = RequiredHandler::AnyHandler);
197     HandlerInfo* handlerForIndex(unsigned, 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* rareCaseProfileForBytecodeOffset(int bytecodeOffset);
410     unsigned rareCaseProfileCountForBytecodeOffset(int bytecodeOffset);
411
412     bool likelyToTakeSlowCase(int bytecodeOffset)
413     {
414         if (!hasBaselineJITProfiling())
415             return false;
416         unsigned value = rareCaseProfileCountForBytecodeOffset(bytecodeOffset);
417         return value >= Options::likelyToTakeSlowCaseMinimumCount();
418     }
419
420     bool couldTakeSlowCase(int bytecodeOffset)
421     {
422         if (!hasBaselineJITProfiling())
423             return false;
424         unsigned value = rareCaseProfileCountForBytecodeOffset(bytecodeOffset);
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     unsigned specialFastCaseProfileCountForBytecodeOffset(int bytecodeOffset)
442     {
443         RareCaseProfile* profile = specialFastCaseProfileForBytecodeOffset(bytecodeOffset);
444         if (!profile)
445             return 0;
446         return profile->m_counter;
447     }
448
449     bool couldTakeSpecialFastCase(int bytecodeOffset)
450     {
451         if (!hasBaselineJITProfiling())
452             return false;
453         unsigned specialFastCaseCount = specialFastCaseProfileCountForBytecodeOffset(bytecodeOffset);
454         return specialFastCaseCount >= Options::couldTakeSlowCaseMinimumCount();
455     }
456
457     bool likelyToTakeDeepestSlowCase(int bytecodeOffset)
458     {
459         if (!hasBaselineJITProfiling())
460             return false;
461         unsigned slowCaseCount = rareCaseProfileCountForBytecodeOffset(bytecodeOffset);
462         unsigned specialFastCaseCount = specialFastCaseProfileCountForBytecodeOffset(bytecodeOffset);
463         unsigned value = slowCaseCount - specialFastCaseCount;
464         return value >= Options::likelyToTakeSlowCaseMinimumCount();
465     }
466
467     unsigned numberOfArrayProfiles() const { return m_arrayProfiles.size(); }
468     const ArrayProfileVector& arrayProfiles() { return m_arrayProfiles; }
469     ArrayProfile* addArrayProfile(unsigned bytecodeOffset)
470     {
471         m_arrayProfiles.append(ArrayProfile(bytecodeOffset));
472         return &m_arrayProfiles.last();
473     }
474     ArrayProfile* getArrayProfile(unsigned bytecodeOffset);
475     ArrayProfile* getOrAddArrayProfile(unsigned bytecodeOffset);
476
477     // Exception handling support
478
479     size_t numberOfExceptionHandlers() const { return m_rareData ? m_rareData->m_exceptionHandlers.size() : 0; }
480     HandlerInfo& exceptionHandler(int index) { RELEASE_ASSERT(m_rareData); return m_rareData->m_exceptionHandlers[index]; }
481
482     bool hasExpressionInfo() { return m_unlinkedCode->hasExpressionInfo(); }
483
484 #if ENABLE(DFG_JIT)
485     Vector<CodeOrigin, 0, UnsafeVectorOverflow>& codeOrigins();
486     
487     // Having code origins implies that there has been some inlining.
488     bool hasCodeOrigins()
489     {
490         return JITCode::isOptimizingJIT(jitType());
491     }
492         
493     bool canGetCodeOrigin(CallSiteIndex index)
494     {
495         if (!hasCodeOrigins())
496             return false;
497         return index.bits() < codeOrigins().size();
498     }
499
500     CodeOrigin codeOrigin(CallSiteIndex index)
501     {
502         return codeOrigins()[index.bits()];
503     }
504
505     bool addFrequentExitSite(const DFG::FrequentExitSite& site)
506     {
507         ASSERT(JITCode::isBaselineCode(jitType()));
508         ConcurrentJITLocker locker(m_lock);
509         return m_exitProfile.add(locker, site);
510     }
511
512     bool hasExitSite(const ConcurrentJITLocker& locker, const DFG::FrequentExitSite& site) const
513     {
514         return m_exitProfile.hasExitSite(locker, site);
515     }
516     bool hasExitSite(const DFG::FrequentExitSite& site) const
517     {
518         ConcurrentJITLocker locker(m_lock);
519         return hasExitSite(locker, site);
520     }
521
522     DFG::ExitProfile& exitProfile() { return m_exitProfile; }
523
524     CompressedLazyOperandValueProfileHolder& lazyOperandValueProfiles()
525     {
526         return m_lazyOperandValueProfiles;
527     }
528 #endif // ENABLE(DFG_JIT)
529
530     // Constant Pool
531 #if ENABLE(DFG_JIT)
532     size_t numberOfIdentifiers() const { return m_unlinkedCode->numberOfIdentifiers() + numberOfDFGIdentifiers(); }
533     size_t numberOfDFGIdentifiers() const;
534     const Identifier& identifier(int index) const;
535 #else
536     size_t numberOfIdentifiers() const { return m_unlinkedCode->numberOfIdentifiers(); }
537     const Identifier& identifier(int index) const { return m_unlinkedCode->identifier(index); }
538 #endif
539
540     Vector<WriteBarrier<Unknown>>& constants() { return m_constantRegisters; }
541     Vector<SourceCodeRepresentation>& constantsSourceCodeRepresentation() { return m_constantsSourceCodeRepresentation; }
542     unsigned addConstant(JSValue v)
543     {
544         unsigned result = m_constantRegisters.size();
545         m_constantRegisters.append(WriteBarrier<Unknown>());
546         m_constantRegisters.last().set(m_globalObject->vm(), m_ownerExecutable.get(), v);
547         m_constantsSourceCodeRepresentation.append(SourceCodeRepresentation::Other);
548         return result;
549     }
550
551     unsigned addConstantLazily()
552     {
553         unsigned result = m_constantRegisters.size();
554         m_constantRegisters.append(WriteBarrier<Unknown>());
555         m_constantsSourceCodeRepresentation.append(SourceCodeRepresentation::Other);
556         return result;
557     }
558
559     WriteBarrier<Unknown>& constantRegister(int index) { return m_constantRegisters[index - FirstConstantRegisterIndex]; }
560     ALWAYS_INLINE bool isConstantRegisterIndex(int index) const { return index >= FirstConstantRegisterIndex; }
561     ALWAYS_INLINE JSValue getConstant(int index) const { return m_constantRegisters[index - FirstConstantRegisterIndex].get(); }
562     ALWAYS_INLINE SourceCodeRepresentation constantSourceCodeRepresentation(int index) const { return m_constantsSourceCodeRepresentation[index - FirstConstantRegisterIndex]; }
563
564     FunctionExecutable* functionDecl(int index) { return m_functionDecls[index].get(); }
565     int numberOfFunctionDecls() { return m_functionDecls.size(); }
566     FunctionExecutable* functionExpr(int index) { return m_functionExprs[index].get(); }
567     
568     RegExp* regexp(int index) const { return m_unlinkedCode->regexp(index); }
569
570     unsigned numberOfConstantBuffers() const
571     {
572         if (!m_rareData)
573             return 0;
574         return m_rareData->m_constantBuffers.size();
575     }
576     unsigned addConstantBuffer(const Vector<JSValue>& buffer)
577     {
578         createRareDataIfNecessary();
579         unsigned size = m_rareData->m_constantBuffers.size();
580         m_rareData->m_constantBuffers.append(buffer);
581         return size;
582     }
583
584     Vector<JSValue>& constantBufferAsVector(unsigned index)
585     {
586         ASSERT(m_rareData);
587         return m_rareData->m_constantBuffers[index];
588     }
589     JSValue* constantBuffer(unsigned index)
590     {
591         return constantBufferAsVector(index).data();
592     }
593
594     Heap* heap() const { return m_heap; }
595     JSGlobalObject* globalObject() { return m_globalObject.get(); }
596
597     JSGlobalObject* globalObjectFor(CodeOrigin);
598
599     BytecodeLivenessAnalysis& livenessAnalysis()
600     {
601         {
602             ConcurrentJITLocker locker(m_lock);
603             if (!!m_livenessAnalysis)
604                 return *m_livenessAnalysis;
605         }
606         std::unique_ptr<BytecodeLivenessAnalysis> analysis =
607             std::make_unique<BytecodeLivenessAnalysis>(this);
608         {
609             ConcurrentJITLocker locker(m_lock);
610             if (!m_livenessAnalysis)
611                 m_livenessAnalysis = WTF::move(analysis);
612             return *m_livenessAnalysis;
613         }
614     }
615     
616     void validate();
617
618     // Jump Tables
619
620     size_t numberOfSwitchJumpTables() const { return m_rareData ? m_rareData->m_switchJumpTables.size() : 0; }
621     SimpleJumpTable& addSwitchJumpTable() { createRareDataIfNecessary(); m_rareData->m_switchJumpTables.append(SimpleJumpTable()); return m_rareData->m_switchJumpTables.last(); }
622     SimpleJumpTable& switchJumpTable(int tableIndex) { RELEASE_ASSERT(m_rareData); return m_rareData->m_switchJumpTables[tableIndex]; }
623     void clearSwitchJumpTables()
624     {
625         if (!m_rareData)
626             return;
627         m_rareData->m_switchJumpTables.clear();
628     }
629
630     size_t numberOfStringSwitchJumpTables() const { return m_rareData ? m_rareData->m_stringSwitchJumpTables.size() : 0; }
631     StringJumpTable& addStringSwitchJumpTable() { createRareDataIfNecessary(); m_rareData->m_stringSwitchJumpTables.append(StringJumpTable()); return m_rareData->m_stringSwitchJumpTables.last(); }
632     StringJumpTable& stringSwitchJumpTable(int tableIndex) { RELEASE_ASSERT(m_rareData); return m_rareData->m_stringSwitchJumpTables[tableIndex]; }
633
634     EvalCodeCache& evalCodeCache() { createRareDataIfNecessary(); return m_rareData->m_evalCodeCache; }
635
636     enum ShrinkMode {
637         // Shrink prior to generating machine code that may point directly into vectors.
638         EarlyShrink,
639
640         // Shrink after generating machine code, and after possibly creating new vectors
641         // and appending to others. At this time it is not safe to shrink certain vectors
642         // because we would have generated machine code that references them directly.
643         LateShrink
644     };
645     void shrinkToFit(ShrinkMode);
646
647     // Functions for controlling when JITting kicks in, in a mixed mode
648     // execution world.
649
650     bool checkIfJITThresholdReached()
651     {
652         return m_llintExecuteCounter.checkIfThresholdCrossedAndSet(this);
653     }
654
655     void dontJITAnytimeSoon()
656     {
657         m_llintExecuteCounter.deferIndefinitely();
658     }
659
660     void jitAfterWarmUp()
661     {
662         m_llintExecuteCounter.setNewThreshold(Options::thresholdForJITAfterWarmUp(), this);
663     }
664
665     void jitSoon()
666     {
667         m_llintExecuteCounter.setNewThreshold(Options::thresholdForJITSoon(), this);
668     }
669
670     const BaselineExecutionCounter& llintExecuteCounter() const
671     {
672         return m_llintExecuteCounter;
673     }
674
675     // Functions for controlling when tiered compilation kicks in. This
676     // controls both when the optimizing compiler is invoked and when OSR
677     // entry happens. Two triggers exist: the loop trigger and the return
678     // trigger. In either case, when an addition to m_jitExecuteCounter
679     // causes it to become non-negative, the optimizing compiler is
680     // invoked. This includes a fast check to see if this CodeBlock has
681     // already been optimized (i.e. replacement() returns a CodeBlock
682     // that was optimized with a higher tier JIT than this one). In the
683     // case of the loop trigger, if the optimized compilation succeeds
684     // (or has already succeeded in the past) then OSR is attempted to
685     // redirect program flow into the optimized code.
686
687     // These functions are called from within the optimization triggers,
688     // and are used as a single point at which we define the heuristics
689     // for how much warm-up is mandated before the next optimization
690     // trigger files. All CodeBlocks start out with optimizeAfterWarmUp(),
691     // as this is called from the CodeBlock constructor.
692
693     // When we observe a lot of speculation failures, we trigger a
694     // reoptimization. But each time, we increase the optimization trigger
695     // to avoid thrashing.
696     JS_EXPORT_PRIVATE unsigned reoptimizationRetryCounter() const;
697     void countReoptimization();
698 #if ENABLE(JIT)
699     static unsigned numberOfLLIntBaselineCalleeSaveRegisters() { return RegisterSet::llintBaselineCalleeSaveRegisters().numberOfSetRegisters(); }
700     static size_t llintBaselineCalleeSaveSpaceAsVirtualRegisters();
701     size_t calleeSaveSpaceAsVirtualRegisters();
702
703     unsigned numberOfDFGCompiles();
704
705     int32_t codeTypeThresholdMultiplier() const;
706
707     int32_t adjustedCounterValue(int32_t desiredThreshold);
708
709     int32_t* addressOfJITExecuteCounter()
710     {
711         return &m_jitExecuteCounter.m_counter;
712     }
713
714     static ptrdiff_t offsetOfJITExecuteCounter() { return OBJECT_OFFSETOF(CodeBlock, m_jitExecuteCounter) + OBJECT_OFFSETOF(BaselineExecutionCounter, m_counter); }
715     static ptrdiff_t offsetOfJITExecutionActiveThreshold() { return OBJECT_OFFSETOF(CodeBlock, m_jitExecuteCounter) + OBJECT_OFFSETOF(BaselineExecutionCounter, m_activeThreshold); }
716     static ptrdiff_t offsetOfJITExecutionTotalCount() { return OBJECT_OFFSETOF(CodeBlock, m_jitExecuteCounter) + OBJECT_OFFSETOF(BaselineExecutionCounter, m_totalCount); }
717
718     const BaselineExecutionCounter& jitExecuteCounter() const { return m_jitExecuteCounter; }
719
720     unsigned optimizationDelayCounter() const { return m_optimizationDelayCounter; }
721
722     // Check if the optimization threshold has been reached, and if not,
723     // adjust the heuristics accordingly. Returns true if the threshold has
724     // been reached.
725     bool checkIfOptimizationThresholdReached();
726
727     // Call this to force the next optimization trigger to fire. This is
728     // rarely wise, since optimization triggers are typically more
729     // expensive than executing baseline code.
730     void optimizeNextInvocation();
731
732     // Call this to prevent optimization from happening again. Note that
733     // optimization will still happen after roughly 2^29 invocations,
734     // so this is really meant to delay that as much as possible. This
735     // is called if optimization failed, and we expect it to fail in
736     // the future as well.
737     void dontOptimizeAnytimeSoon();
738
739     // Call this to reinitialize the counter to its starting state,
740     // forcing a warm-up to happen before the next optimization trigger
741     // fires. This is called in the CodeBlock constructor. It also
742     // makes sense to call this if an OSR exit occurred. Note that
743     // OSR exit code is code generated, so the value of the execute
744     // counter that this corresponds to is also available directly.
745     void optimizeAfterWarmUp();
746
747     // Call this to force an optimization trigger to fire only after
748     // a lot of warm-up.
749     void optimizeAfterLongWarmUp();
750
751     // Call this to cause an optimization trigger to fire soon, but
752     // not necessarily the next one. This makes sense if optimization
753     // succeeds. Successfuly optimization means that all calls are
754     // relinked to the optimized code, so this only affects call
755     // frames that are still executing this CodeBlock. The value here
756     // is tuned to strike a balance between the cost of OSR entry
757     // (which is too high to warrant making every loop back edge to
758     // trigger OSR immediately) and the cost of executing baseline
759     // code (which is high enough that we don't necessarily want to
760     // have a full warm-up). The intuition for calling this instead of
761     // optimizeNextInvocation() is for the case of recursive functions
762     // with loops. Consider that there may be N call frames of some
763     // recursive function, for a reasonably large value of N. The top
764     // one triggers optimization, and then returns, and then all of
765     // the others return. We don't want optimization to be triggered on
766     // each return, as that would be superfluous. It only makes sense
767     // to trigger optimization if one of those functions becomes hot
768     // in the baseline code.
769     void optimizeSoon();
770
771     void forceOptimizationSlowPathConcurrently();
772
773     void setOptimizationThresholdBasedOnCompilationResult(CompilationResult);
774     
775     uint32_t osrExitCounter() const { return m_osrExitCounter; }
776
777     void countOSRExit() { m_osrExitCounter++; }
778
779     uint32_t* addressOfOSRExitCounter() { return &m_osrExitCounter; }
780
781     static ptrdiff_t offsetOfOSRExitCounter() { return OBJECT_OFFSETOF(CodeBlock, m_osrExitCounter); }
782
783     uint32_t adjustedExitCountThreshold(uint32_t desiredThreshold);
784     uint32_t exitCountThresholdForReoptimization();
785     uint32_t exitCountThresholdForReoptimizationFromLoop();
786     bool shouldReoptimizeNow();
787     bool shouldReoptimizeFromLoopNow();
788
789     void setCalleeSaveRegisters(RegisterSet);
790     void setCalleeSaveRegisters(std::unique_ptr<RegisterAtOffsetList>);
791     
792     RegisterAtOffsetList* calleeSaveRegisters() const { return m_calleeSaveRegisters.get(); }
793 #else // No JIT
794     static unsigned numberOfLLIntBaselineCalleeSaveRegisters() { return 0; }
795     static size_t llintBaselineCalleeSaveSpaceAsVirtualRegisters() { return 0; };
796     void optimizeAfterWarmUp() { }
797     unsigned numberOfDFGCompiles() { return 0; }
798 #endif
799
800     bool shouldOptimizeNow();
801     void updateAllValueProfilePredictions();
802     void updateAllArrayPredictions();
803     void updateAllPredictions();
804
805     unsigned frameRegisterCount();
806     int stackPointerOffset();
807
808     bool hasOpDebugForLineAndColumn(unsigned line, unsigned column);
809
810     bool hasDebuggerRequests() const { return m_debuggerRequests; }
811     void* debuggerRequestsAddress() { return &m_debuggerRequests; }
812
813     void addBreakpoint(unsigned numBreakpoints);
814     void removeBreakpoint(unsigned numBreakpoints)
815     {
816         ASSERT(m_numBreakpoints >= numBreakpoints);
817         m_numBreakpoints -= numBreakpoints;
818     }
819
820     enum SteppingMode {
821         SteppingModeDisabled,
822         SteppingModeEnabled
823     };
824     void setSteppingMode(SteppingMode);
825
826     void clearDebuggerRequests()
827     {
828         m_steppingMode = SteppingModeDisabled;
829         m_numBreakpoints = 0;
830     }
831     
832     // FIXME: Make these remaining members private.
833
834     int m_numLocalRegistersForCalleeSaves;
835     int m_numCalleeRegisters;
836     int m_numVars;
837     bool m_isConstructor : 1;
838     
839     // This is intentionally public; it's the responsibility of anyone doing any
840     // of the following to hold the lock:
841     //
842     // - Modifying any inline cache in this code block.
843     //
844     // - Quering any inline cache in this code block, from a thread other than
845     //   the main thread.
846     //
847     // Additionally, it's only legal to modify the inline cache on the main
848     // thread. This means that the main thread can query the inline cache without
849     // locking. This is crucial since executing the inline cache is effectively
850     // "querying" it.
851     //
852     // Another exception to the rules is that the GC can do whatever it wants
853     // without holding any locks, because the GC is guaranteed to wait until any
854     // concurrent compilation threads finish what they're doing.
855     mutable ConcurrentJITLock m_lock;
856     
857     bool m_shouldAlwaysBeInlined; // Not a bitfield because the JIT wants to store to it.
858     bool m_allTransitionsHaveBeenMarked : 1; // Initialized and used on every GC.
859     
860     bool m_didFailFTLCompilation : 1;
861     bool m_hasBeenCompiledWithFTL : 1;
862
863     // Internal methods for use by validation code. It would be private if it wasn't
864     // for the fact that we use it from anonymous namespaces.
865     void beginValidationDidFail();
866     NO_RETURN_DUE_TO_CRASH void endValidationDidFail();
867
868     bool isKnownToBeLiveDuringGC(); // Will only return valid results when called during GC. Assumes that you've already established that the owner executable is live.
869
870     struct RareData {
871         WTF_MAKE_FAST_ALLOCATED;
872     public:
873         Vector<HandlerInfo> m_exceptionHandlers;
874
875         // Buffers used for large array literals
876         Vector<Vector<JSValue>> m_constantBuffers;
877
878         // Jump Tables
879         Vector<SimpleJumpTable> m_switchJumpTables;
880         Vector<StringJumpTable> m_stringSwitchJumpTables;
881
882         EvalCodeCache m_evalCodeCache;
883     };
884
885     void clearExceptionHandlers()
886     {
887         if (m_rareData)
888             m_rareData->m_exceptionHandlers.clear();
889     }
890
891     void appendExceptionHandler(const HandlerInfo& handler)
892     {
893         createRareDataIfNecessary(); // We may be handling the exception of an inlined call frame.
894         m_rareData->m_exceptionHandlers.append(handler);
895     }
896
897 protected:
898     virtual void visitWeakReferences(SlotVisitor&) override;
899     virtual void finalizeUnconditionally() override;
900     void finalizeLLIntInlineCaches();
901     void finalizeBaselineJITInlineCaches();
902
903 #if ENABLE(DFG_JIT)
904     void tallyFrequentExitSites();
905 #else
906     void tallyFrequentExitSites() { }
907 #endif
908
909 private:
910     friend class CodeBlockSet;
911     
912     CodeBlock* specialOSREntryBlockOrNull();
913     
914     void noticeIncomingCall(ExecState* callerFrame);
915     
916     double optimizationThresholdScalingFactor();
917
918     void updateAllPredictionsAndCountLiveness(unsigned& numberOfLiveNonArgumentValueProfiles, unsigned& numberOfSamplesInProfiles);
919
920     void setConstantRegisters(const Vector<WriteBarrier<Unknown>>& constants, const Vector<SourceCodeRepresentation>& constantsSourceCodeRepresentation)
921     {
922         ASSERT(constants.size() == constantsSourceCodeRepresentation.size());
923         size_t count = constants.size();
924         m_constantRegisters.resizeToFit(count);
925         for (size_t i = 0; i < count; i++)
926             m_constantRegisters[i].set(*m_vm, ownerExecutable(), constants[i].get());
927         m_constantsSourceCodeRepresentation = constantsSourceCodeRepresentation;
928     }
929
930     void replaceConstant(int index, JSValue value)
931     {
932         ASSERT(isConstantRegisterIndex(index) && static_cast<size_t>(index - FirstConstantRegisterIndex) < m_constantRegisters.size());
933         m_constantRegisters[index - FirstConstantRegisterIndex].set(m_globalObject->vm(), m_ownerExecutable.get(), value);
934     }
935
936     void dumpBytecode(
937         PrintStream&, ExecState*, const Instruction* begin, const Instruction*&,
938         const StubInfoMap& = StubInfoMap(), const CallLinkInfoMap& = CallLinkInfoMap());
939
940     CString registerName(int r) const;
941     CString constantName(int index) const;
942     void printUnaryOp(PrintStream&, ExecState*, int location, const Instruction*&, const char* op);
943     void printBinaryOp(PrintStream&, ExecState*, int location, const Instruction*&, const char* op);
944     void printConditionalJump(PrintStream&, ExecState*, const Instruction*, const Instruction*&, int location, const char* op);
945     void printGetByIdOp(PrintStream&, ExecState*, int location, const Instruction*&);
946     void printGetByIdCacheStatus(PrintStream&, ExecState*, int location, const StubInfoMap&);
947     enum CacheDumpMode { DumpCaches, DontDumpCaches };
948     void printCallOp(PrintStream&, ExecState*, int location, const Instruction*&, const char* op, CacheDumpMode, bool& hasPrintedProfiling, const CallLinkInfoMap&);
949     void printPutByIdOp(PrintStream&, ExecState*, int location, const Instruction*&, const char* op);
950     void printPutByIdCacheStatus(PrintStream&, int location, const StubInfoMap&);
951     void printLocationAndOp(PrintStream&, ExecState*, int location, const Instruction*&, const char* op);
952     void printLocationOpAndRegisterOperand(PrintStream&, ExecState*, int location, const Instruction*& it, const char* op, int operand);
953
954     void beginDumpProfiling(PrintStream&, bool& hasPrintedProfiling);
955     void dumpValueProfiling(PrintStream&, const Instruction*&, bool& hasPrintedProfiling);
956     void dumpArrayProfiling(PrintStream&, const Instruction*&, bool& hasPrintedProfiling);
957     void dumpRareCaseProfile(PrintStream&, const char* name, RareCaseProfile*, bool& hasPrintedProfiling);
958         
959     bool shouldVisitStrongly();
960     bool shouldJettisonDueToWeakReference();
961     bool shouldJettisonDueToOldAge();
962     
963     void propagateTransitions(SlotVisitor&);
964     void determineLiveness(SlotVisitor&);
965         
966     void stronglyVisitStrongReferences(SlotVisitor&);
967     void stronglyVisitWeakReferences(SlotVisitor&);
968     void visitOSRExitTargets(SlotVisitor&);
969
970     std::chrono::milliseconds timeSinceCreation()
971     {
972         return std::chrono::duration_cast<std::chrono::milliseconds>(
973             std::chrono::steady_clock::now() - m_creationTime);
974     }
975
976     void createRareDataIfNecessary()
977     {
978         if (!m_rareData)
979             m_rareData = std::make_unique<RareData>();
980     }
981
982     void insertBasicBlockBoundariesForControlFlowProfiler(Vector<Instruction, 0, UnsafeVectorOverflow>&);
983
984     WriteBarrier<UnlinkedCodeBlock> m_unlinkedCode;
985     int m_numParameters;
986     union {
987         unsigned m_debuggerRequests;
988         struct {
989             unsigned m_hasDebuggerStatement : 1;
990             unsigned m_steppingMode : 1;
991             unsigned m_numBreakpoints : 30;
992         };
993     };
994     WriteBarrier<ExecutableBase> m_ownerExecutable;
995     VM* m_vm;
996
997     RefCountedArray<Instruction> m_instructions;
998     VirtualRegister m_thisRegister;
999     VirtualRegister m_scopeRegister;
1000     VirtualRegister m_lexicalEnvironmentRegister;
1001
1002     bool m_isStrictMode;
1003     bool m_needsActivation;
1004
1005     Atomic<bool> m_visitAggregateHasBeenCalled;
1006     Atomic<bool> m_visitStronglyHasBeenCalled;
1007
1008     RefPtr<SourceProvider> m_source;
1009     unsigned m_sourceOffset;
1010     unsigned m_firstLineColumnOffset;
1011     CodeType m_codeType;
1012
1013     Vector<LLIntCallLinkInfo> m_llintCallLinkInfos;
1014     SentinelLinkedList<LLIntCallLinkInfo, BasicRawSentinelNode<LLIntCallLinkInfo>> m_incomingLLIntCalls;
1015     RefPtr<JITCode> m_jitCode;
1016 #if ENABLE(JIT)
1017     std::unique_ptr<RegisterAtOffsetList> m_calleeSaveRegisters;
1018     Bag<StructureStubInfo> m_stubInfos;
1019     Bag<ByValInfo> m_byValInfos;
1020     Bag<CallLinkInfo> m_callLinkInfos;
1021     SentinelLinkedList<CallLinkInfo, BasicRawSentinelNode<CallLinkInfo>> m_incomingCalls;
1022     SentinelLinkedList<PolymorphicCallNode, BasicRawSentinelNode<PolymorphicCallNode>> m_incomingPolymorphicCalls;
1023 #endif
1024     std::unique_ptr<CompactJITCodeMap> m_jitCodeMap;
1025 #if ENABLE(DFG_JIT)
1026     // This is relevant to non-DFG code blocks that serve as the profiled code block
1027     // for DFG code blocks.
1028     DFG::ExitProfile m_exitProfile;
1029     CompressedLazyOperandValueProfileHolder m_lazyOperandValueProfiles;
1030 #endif
1031     Vector<ValueProfile> m_argumentValueProfiles;
1032     Vector<ValueProfile> m_valueProfiles;
1033     SegmentedVector<RareCaseProfile, 8> m_rareCaseProfiles;
1034     SegmentedVector<RareCaseProfile, 8> m_specialFastCaseProfiles;
1035     Vector<ArrayAllocationProfile> m_arrayAllocationProfiles;
1036     ArrayProfileVector m_arrayProfiles;
1037     Vector<ObjectAllocationProfile> m_objectAllocationProfiles;
1038
1039     // Constant Pool
1040     COMPILE_ASSERT(sizeof(Register) == sizeof(WriteBarrier<Unknown>), Register_must_be_same_size_as_WriteBarrier_Unknown);
1041     // TODO: This could just be a pointer to m_unlinkedCodeBlock's data, but the DFG mutates
1042     // it, so we're stuck with it for now.
1043     Vector<WriteBarrier<Unknown>> m_constantRegisters;
1044     Vector<SourceCodeRepresentation> m_constantsSourceCodeRepresentation;
1045     Vector<WriteBarrier<FunctionExecutable>> m_functionDecls;
1046     Vector<WriteBarrier<FunctionExecutable>> m_functionExprs;
1047
1048     RefPtr<CodeBlock> m_alternative;
1049     
1050     BaselineExecutionCounter m_llintExecuteCounter;
1051
1052     BaselineExecutionCounter m_jitExecuteCounter;
1053     int32_t m_totalJITExecutions;
1054     uint32_t m_osrExitCounter;
1055     uint16_t m_optimizationDelayCounter;
1056     uint16_t m_reoptimizationRetryCounter;
1057
1058     std::chrono::steady_clock::time_point m_creationTime;
1059
1060     mutable CodeBlockHash m_hash;
1061
1062     std::unique_ptr<BytecodeLivenessAnalysis> m_livenessAnalysis;
1063
1064     std::unique_ptr<RareData> m_rareData;
1065 #if ENABLE(JIT)
1066     DFG::CapabilityLevel m_capabilityLevelState;
1067 #endif
1068 };
1069
1070 // Program code is not marked by any function, so we make the global object
1071 // responsible for marking it.
1072
1073 class GlobalCodeBlock : public CodeBlock {
1074 protected:
1075     GlobalCodeBlock(CopyParsedBlockTag, GlobalCodeBlock& other)
1076     : CodeBlock(CopyParsedBlock, other)
1077     {
1078     }
1079         
1080     GlobalCodeBlock(ScriptExecutable* ownerExecutable, UnlinkedCodeBlock* unlinkedCodeBlock, JSScope* scope, PassRefPtr<SourceProvider> sourceProvider, unsigned sourceOffset, unsigned firstLineColumnOffset)
1081         : CodeBlock(ownerExecutable, unlinkedCodeBlock, scope, sourceProvider, sourceOffset, firstLineColumnOffset)
1082     {
1083     }
1084 };
1085
1086 class ProgramCodeBlock : public GlobalCodeBlock {
1087 public:
1088     ProgramCodeBlock(CopyParsedBlockTag, ProgramCodeBlock& other)
1089     : GlobalCodeBlock(CopyParsedBlock, other)
1090     {
1091     }
1092
1093     ProgramCodeBlock(ProgramExecutable* ownerExecutable, UnlinkedProgramCodeBlock* unlinkedCodeBlock, JSScope* scope, PassRefPtr<SourceProvider> sourceProvider, unsigned firstLineColumnOffset)
1094         : GlobalCodeBlock(ownerExecutable, unlinkedCodeBlock, scope, sourceProvider, 0, firstLineColumnOffset)
1095     {
1096     }
1097
1098 #if ENABLE(JIT)
1099 protected:
1100     virtual CodeBlock* replacement() override;
1101     virtual DFG::CapabilityLevel capabilityLevelInternal() override;
1102 #endif
1103 };
1104
1105 class ModuleProgramCodeBlock : public GlobalCodeBlock {
1106 public:
1107     ModuleProgramCodeBlock(CopyParsedBlockTag, ModuleProgramCodeBlock& other)
1108         : GlobalCodeBlock(CopyParsedBlock, other)
1109     {
1110     }
1111
1112     ModuleProgramCodeBlock(ModuleProgramExecutable* ownerExecutable, UnlinkedModuleProgramCodeBlock* unlinkedCodeBlock, JSScope* scope, PassRefPtr<SourceProvider> sourceProvider, unsigned firstLineColumnOffset)
1113         : GlobalCodeBlock(ownerExecutable, unlinkedCodeBlock, scope, sourceProvider, 0, firstLineColumnOffset)
1114     {
1115     }
1116
1117 #if ENABLE(JIT)
1118 protected:
1119     virtual CodeBlock* replacement() override;
1120     virtual DFG::CapabilityLevel capabilityLevelInternal() override;
1121 #endif
1122 };
1123
1124 class EvalCodeBlock : public GlobalCodeBlock {
1125 public:
1126     EvalCodeBlock(CopyParsedBlockTag, EvalCodeBlock& other)
1127         : GlobalCodeBlock(CopyParsedBlock, other)
1128     {
1129     }
1130         
1131     EvalCodeBlock(EvalExecutable* ownerExecutable, UnlinkedEvalCodeBlock* unlinkedCodeBlock, JSScope* scope, PassRefPtr<SourceProvider> sourceProvider)
1132         : GlobalCodeBlock(ownerExecutable, unlinkedCodeBlock, scope, sourceProvider, 0, 1)
1133     {
1134     }
1135     
1136     const Identifier& variable(unsigned index) { return unlinkedEvalCodeBlock()->variable(index); }
1137     unsigned numVariables() { return unlinkedEvalCodeBlock()->numVariables(); }
1138     
1139 #if ENABLE(JIT)
1140 protected:
1141     virtual CodeBlock* replacement() override;
1142     virtual DFG::CapabilityLevel capabilityLevelInternal() override;
1143 #endif
1144     
1145 private:
1146     UnlinkedEvalCodeBlock* unlinkedEvalCodeBlock() const { return jsCast<UnlinkedEvalCodeBlock*>(unlinkedCodeBlock()); }
1147 };
1148
1149 class FunctionCodeBlock : public CodeBlock {
1150 public:
1151     FunctionCodeBlock(CopyParsedBlockTag, FunctionCodeBlock& other)
1152         : CodeBlock(CopyParsedBlock, other)
1153     {
1154     }
1155
1156     FunctionCodeBlock(FunctionExecutable* ownerExecutable, UnlinkedFunctionCodeBlock* unlinkedCodeBlock, JSScope* scope, PassRefPtr<SourceProvider> sourceProvider, unsigned sourceOffset, unsigned firstLineColumnOffset)
1157         : CodeBlock(ownerExecutable, unlinkedCodeBlock, scope, sourceProvider, sourceOffset, firstLineColumnOffset)
1158     {
1159     }
1160     
1161 #if ENABLE(JIT)
1162 protected:
1163     virtual CodeBlock* replacement() override;
1164     virtual DFG::CapabilityLevel capabilityLevelInternal() override;
1165 #endif
1166 };
1167
1168 #if ENABLE(WEBASSEMBLY)
1169 class WebAssemblyCodeBlock : public CodeBlock {
1170 public:
1171     WebAssemblyCodeBlock(CopyParsedBlockTag, WebAssemblyCodeBlock& other)
1172         : CodeBlock(CopyParsedBlock, other)
1173     {
1174     }
1175
1176     WebAssemblyCodeBlock(WebAssemblyExecutable* ownerExecutable, VM& vm, JSGlobalObject* globalObject)
1177         : CodeBlock(ownerExecutable, vm, globalObject)
1178     {
1179     }
1180
1181 #if ENABLE(JIT)
1182 protected:
1183     virtual CodeBlock* replacement() override;
1184     virtual DFG::CapabilityLevel capabilityLevelInternal() override;
1185 #endif
1186 };
1187 #endif
1188
1189 inline Register& ExecState::r(int index)
1190 {
1191     CodeBlock* codeBlock = this->codeBlock();
1192     if (codeBlock->isConstantRegisterIndex(index))
1193         return *reinterpret_cast<Register*>(&codeBlock->constantRegister(index));
1194     return this[index];
1195 }
1196
1197 inline Register& ExecState::r(VirtualRegister reg)
1198 {
1199     return r(reg.offset());
1200 }
1201
1202 inline Register& ExecState::uncheckedR(int index)
1203 {
1204     RELEASE_ASSERT(index < FirstConstantRegisterIndex);
1205     return this[index];
1206 }
1207
1208 inline Register& ExecState::uncheckedR(VirtualRegister reg)
1209 {
1210     return uncheckedR(reg.offset());
1211 }
1212
1213 inline void CodeBlock::clearMarks()
1214 {
1215     m_visitStronglyHasBeenCalled.store(false, std::memory_order_relaxed);
1216     m_visitAggregateHasBeenCalled.store(false, std::memory_order_relaxed);
1217 }
1218
1219 inline void CodeBlockSet::mark(void* candidateCodeBlock)
1220 {
1221     // We have to check for 0 and -1 because those are used by the HashMap as markers.
1222     uintptr_t value = reinterpret_cast<uintptr_t>(candidateCodeBlock);
1223     
1224     // This checks for both of those nasty cases in one go.
1225     // 0 + 1 = 1
1226     // -1 + 1 = 0
1227     if (value + 1 <= 1)
1228         return;
1229
1230     CodeBlock* codeBlock = static_cast<CodeBlock*>(candidateCodeBlock); 
1231     if (!m_oldCodeBlocks.contains(codeBlock) && !m_newCodeBlocks.contains(codeBlock))
1232         return;
1233
1234     mark(codeBlock);
1235 }
1236
1237 inline void CodeBlockSet::mark(CodeBlock* codeBlock)
1238 {
1239     if (!codeBlock)
1240         return;
1241     
1242     // Force GC to visit all CodeBlocks on the stack, including old CodeBlocks
1243     // that have not executed a barrier. This is overkill, but we have always
1244     // done this, and it might help us recover gracefully if we forget to execute
1245     // a barrier when a CodeBlock needs it.
1246     codeBlock->clearMarks();
1247
1248     m_currentlyExecuting.add(codeBlock);
1249 }
1250
1251 template <typename Functor> inline void ScriptExecutable::forEachCodeBlock(Functor&& functor)
1252 {
1253     switch (type()) {
1254     case ProgramExecutableType: {
1255         if (CodeBlock* codeBlock = jsCast<ProgramExecutable*>(this)->m_programCodeBlock.get())
1256             codeBlock->forEachRelatedCodeBlock(std::forward<Functor>(functor));
1257         break;
1258     }
1259
1260     case EvalExecutableType: {
1261         if (CodeBlock* codeBlock = jsCast<EvalExecutable*>(this)->m_evalCodeBlock.get())
1262             codeBlock->forEachRelatedCodeBlock(std::forward<Functor>(functor));
1263         break;
1264     }
1265
1266     case FunctionExecutableType: {
1267         Functor f(std::forward<Functor>(functor));
1268         FunctionExecutable* executable = jsCast<FunctionExecutable*>(this);
1269         if (CodeBlock* codeBlock = executable->m_codeBlockForCall.get())
1270             codeBlock->forEachRelatedCodeBlock(f);
1271         if (CodeBlock* codeBlock = executable->m_codeBlockForConstruct.get())
1272             codeBlock->forEachRelatedCodeBlock(f);
1273         break;
1274     }
1275
1276     case ModuleProgramExecutableType: {
1277         if (CodeBlock* codeBlock = jsCast<ModuleProgramExecutable*>(this)->m_moduleProgramCodeBlock.get())
1278             codeBlock->forEachRelatedCodeBlock(std::forward<Functor>(functor));
1279         break;
1280     }
1281
1282     default:
1283         RELEASE_ASSERT_NOT_REACHED();
1284     }
1285 }
1286
1287 } // namespace JSC
1288
1289 #endif // CodeBlock_h