LCOV - code coverage report
Current view: top level - js/src/jit - CompileInfo.h (source / functions) Hit Total Coverage
Test: output.info Lines: 169 227 74.4 %
Date: 2017-07-14 16:53:18 Functions: 55 68 80.9 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
       2             :  * vim: set ts=8 sts=4 et sw=4 tw=99:
       3             :  * This Source Code Form is subject to the terms of the Mozilla Public
       4             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       5             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
       6             : 
       7             : #ifndef jit_CompileInfo_h
       8             : #define jit_CompileInfo_h
       9             : 
      10             : #include "mozilla/Maybe.h"
      11             : 
      12             : #include "jsfun.h"
      13             : 
      14             : #include "jit/JitAllocPolicy.h"
      15             : #include "jit/JitFrames.h"
      16             : #include "jit/Registers.h"
      17             : #include "vm/EnvironmentObject.h"
      18             : 
      19             : namespace js {
      20             : namespace jit {
      21             : 
      22             : class TrackedOptimizations;
      23             : 
      24             : inline unsigned
      25        2714 : StartArgSlot(JSScript* script)
      26             : {
      27             :     // Reserved slots:
      28             :     // Slot 0: Environment chain.
      29             :     // Slot 1: Return value.
      30             : 
      31             :     // When needed:
      32             :     // Slot 2: Argumentsobject.
      33             : 
      34             :     // Note: when updating this, please also update the assert in SnapshotWriter::startFrame
      35        2714 :     return 2 + (script->argumentsHasVarBinding() ? 1 : 0);
      36             : }
      37             : 
      38             : inline unsigned
      39        1846 : CountArgSlots(JSScript* script, JSFunction* fun)
      40             : {
      41             :     // Slot x + 0: This value.
      42             :     // Slot x + 1: Argument 1.
      43             :     // ...
      44             :     // Slot x + n: Argument n.
      45             : 
      46             :     // Note: when updating this, please also update the assert in SnapshotWriter::startFrame
      47        1846 :     return StartArgSlot(script) + (fun ? fun->nargs() + 1 : 0);
      48             : }
      49             : 
      50             : 
      51             : // The compiler at various points needs to be able to store references to the
      52             : // current inline path (the sequence of scripts and call-pcs that lead to the
      53             : // current function being inlined).
      54             : //
      55             : // To support this, the top-level IonBuilder keeps a tree that records the
      56             : // inlinings done during compilation.
      57             : class InlineScriptTree {
      58             :     // InlineScriptTree for the caller
      59             :     InlineScriptTree* caller_;
      60             : 
      61             :     // PC in the caller corresponding to this script.
      62             :     jsbytecode* callerPc_;
      63             : 
      64             :     // Script for this entry.
      65             :     JSScript* script_;
      66             : 
      67             :     // Child entries (linked together by nextCallee pointer)
      68             :     InlineScriptTree* children_;
      69             :     InlineScriptTree* nextCallee_;
      70             : 
      71             :   public:
      72         179 :     InlineScriptTree(InlineScriptTree* caller, jsbytecode* callerPc, JSScript* script)
      73         179 :       : caller_(caller), callerPc_(callerPc), script_(script),
      74         179 :         children_(nullptr), nextCallee_(nullptr)
      75         179 :     {}
      76             : 
      77             :     static InlineScriptTree* New(TempAllocator* allocator, InlineScriptTree* caller,
      78             :                                  jsbytecode* callerPc, JSScript* script);
      79             : 
      80             :     InlineScriptTree* addCallee(TempAllocator* allocator, jsbytecode* callerPc,
      81             :                                 JSScript* calleeScript);
      82             : 
      83         349 :     InlineScriptTree* caller() const {
      84         349 :         return caller_;
      85             :     }
      86             : 
      87        2008 :     bool isOutermostCaller() const {
      88        2008 :         return caller_ == nullptr;
      89             :     }
      90           0 :     bool hasCaller() const {
      91           0 :         return caller_ != nullptr;
      92             :     }
      93             :     InlineScriptTree* outermostCaller() {
      94             :         if (isOutermostCaller())
      95             :             return this;
      96             :         return caller_->outermostCaller();
      97             :     }
      98             : 
      99         333 :     jsbytecode* callerPc() const {
     100         333 :         return callerPc_;
     101             :     }
     102             : 
     103       23957 :     JSScript* script() const {
     104       23957 :         return script_;
     105             :     }
     106             : 
     107           0 :     bool hasChildren() const {
     108           0 :         return children_ != nullptr;
     109             :     }
     110           0 :     InlineScriptTree* firstChild() const {
     111           0 :         MOZ_ASSERT(hasChildren());
     112           0 :         return children_;
     113             :     }
     114             : 
     115           0 :     bool hasNextCallee() const {
     116           0 :         return nextCallee_ != nullptr;
     117             :     }
     118           0 :     InlineScriptTree* nextCallee() const {
     119           0 :         MOZ_ASSERT(hasNextCallee());
     120           0 :         return nextCallee_;
     121             :     }
     122             : 
     123           0 :     unsigned depth() const {
     124           0 :         if (isOutermostCaller())
     125           0 :             return 1;
     126           0 :         return 1 + caller_->depth();
     127             :     }
     128             : };
     129             : 
     130             : class BytecodeSite : public TempObject
     131             : {
     132             :     // InlineScriptTree identifying innermost active function at site.
     133             :     InlineScriptTree* tree_;
     134             : 
     135             :     // Bytecode address within innermost active function.
     136             :     jsbytecode* pc_;
     137             : 
     138             :     // Optimization information at the pc.
     139             :     TrackedOptimizations* optimizations_;
     140             : 
     141             :   public:
     142           0 :     BytecodeSite()
     143           0 :       : tree_(nullptr), pc_(nullptr), optimizations_(nullptr)
     144           0 :     {}
     145             : 
     146       23457 :     BytecodeSite(InlineScriptTree* tree, jsbytecode* pc)
     147       23457 :       : tree_(tree), pc_(pc), optimizations_(nullptr)
     148             :     {
     149       23457 :         MOZ_ASSERT(tree_ != nullptr);
     150       23457 :         MOZ_ASSERT(pc_ != nullptr);
     151       23457 :     }
     152             : 
     153       43059 :     InlineScriptTree* tree() const {
     154       43059 :         return tree_;
     155             :     }
     156             : 
     157       12154 :     jsbytecode* pc() const {
     158       12154 :         return pc_;
     159             :     }
     160             : 
     161         465 :     JSScript* script() const {
     162         465 :         return tree_ ? tree_->script() : nullptr;
     163             :     }
     164             : 
     165       14540 :     bool hasOptimizations() const {
     166       14540 :         return !!optimizations_;
     167             :     }
     168             : 
     169           0 :     TrackedOptimizations* optimizations() const {
     170           0 :         MOZ_ASSERT(hasOptimizations());
     171           0 :         return optimizations_;
     172             :     }
     173             : 
     174           0 :     void setOptimizations(TrackedOptimizations* optimizations) {
     175           0 :         optimizations_ = optimizations;
     176           0 :     }
     177             : };
     178             : 
     179             : enum AnalysisMode {
     180             :     /* JavaScript execution, not analysis. */
     181             :     Analysis_None,
     182             : 
     183             :     /*
     184             :      * MIR analysis performed when invoking 'new' on a script, to determine
     185             :      * definite properties. Used by the optimizing JIT.
     186             :      */
     187             :     Analysis_DefiniteProperties,
     188             : 
     189             :     /*
     190             :      * MIR analysis performed when executing a script which uses its arguments,
     191             :      * when it is not known whether a lazy arguments value can be used.
     192             :      */
     193             :     Analysis_ArgumentsUsage
     194             : };
     195             : 
     196             : // Contains information about the compilation source for IR being generated.
     197         136 : class CompileInfo
     198             : {
     199             :   public:
     200         179 :     CompileInfo(JSScript* script, JSFunction* fun, jsbytecode* osrPc,
     201             :                 AnalysisMode analysisMode, bool scriptNeedsArgsObj,
     202             :                 InlineScriptTree* inlineScriptTree)
     203         179 :       : script_(script), fun_(fun), osrPc_(osrPc),
     204             :         analysisMode_(analysisMode), scriptNeedsArgsObj_(scriptNeedsArgsObj),
     205         179 :         hadOverflowBailout_(script->hadOverflowBailout()),
     206         179 :         mayReadFrameArgsDirectly_(script->mayReadFrameArgsDirectly()),
     207         537 :         inlineScriptTree_(inlineScriptTree)
     208             :     {
     209         179 :         MOZ_ASSERT_IF(osrPc, JSOp(*osrPc) == JSOP_LOOPENTRY);
     210             : 
     211             :         // The function here can flow in from anywhere so look up the canonical
     212             :         // function to ensure that we do not try to embed a nursery pointer in
     213             :         // jit-code. Precisely because it can flow in from anywhere, it's not
     214             :         // guaranteed to be non-lazy. Hence, don't access its script!
     215         179 :         if (fun_) {
     216         179 :             fun_ = fun_->nonLazyScript()->functionNonDelazifying();
     217         179 :             MOZ_ASSERT(fun_->isTenured());
     218             :         }
     219             : 
     220         358 :         nimplicit_ = StartArgSlot(script)                   /* env chain and argument obj */
     221         179 :                    + (fun ? 1 : 0);                         /* this */
     222         179 :         nargs_ = fun ? fun->nargs() : 0;
     223         179 :         nlocals_ = script->nfixed();
     224             : 
     225             :         // An extra slot is needed for global scopes because INITGLEXICAL (stack
     226             :         // depth 1) is compiled as a SETPROP (stack depth 2) on the global lexical
     227             :         // scope.
     228         179 :         uint32_t extra = script->isGlobalCode() ? 1 : 0;
     229         179 :         nstack_ = Max<unsigned>(script->nslots() - script->nfixed(), MinJITStackSize) + extra;
     230         179 :         nslots_ = nimplicit_ + nargs_ + nlocals_ + nstack_;
     231             : 
     232             :         // For derived class constructors, find and cache the frame slot for
     233             :         // the .this binding. This slot is assumed to be always
     234             :         // observable. See isObservableFrameSlot.
     235         179 :         if (script->isDerivedClassConstructor()) {
     236           0 :             MOZ_ASSERT(script->functionHasThisBinding());
     237           0 :             CompileRuntime* runtime = GetJitContext()->runtime;
     238           0 :             for (BindingIter bi(script); bi; bi++) {
     239           0 :                 if (bi.name() != runtime->names().dotThis)
     240           0 :                     continue;
     241           0 :                 BindingLocation loc = bi.location();
     242           0 :                 if (loc.kind() == BindingLocation::Kind::Frame) {
     243           0 :                     thisSlotForDerivedClassConstructor_ = mozilla::Some(localSlot(loc.slot()));
     244           0 :                     break;
     245             :                 }
     246             :             }
     247             :         }
     248             : 
     249             :         // If the script uses an environment in body, the environment chain
     250             :         // will need to be observable.
     251         179 :         needsBodyEnvironmentObject_ = script->needsBodyEnvironment();
     252         179 :     }
     253             : 
     254           0 :     explicit CompileInfo(unsigned nlocals)
     255           0 :       : script_(nullptr), fun_(nullptr), osrPc_(nullptr),
     256             :         analysisMode_(Analysis_None), scriptNeedsArgsObj_(false),
     257             :         mayReadFrameArgsDirectly_(false), inlineScriptTree_(nullptr),
     258           0 :         needsBodyEnvironmentObject_(false)
     259             :     {
     260           0 :         nimplicit_ = 0;
     261           0 :         nargs_ = 0;
     262           0 :         nlocals_ = nlocals;
     263           0 :         nstack_ = 1;  /* For FunctionCompiler::pushPhiInput/popPhiOutput */
     264           0 :         nslots_ = nlocals_ + nstack_;
     265           0 :     }
     266             : 
     267       51618 :     JSScript* script() const {
     268       51618 :         return script_;
     269             :     }
     270       30028 :     bool compilingWasm() const {
     271       30028 :         return script() == nullptr;
     272             :     }
     273       25636 :     JSFunction* funMaybeLazy() const {
     274       25636 :         return fun_;
     275             :     }
     276           0 :     ModuleObject* module() const {
     277           0 :         return script_->module();
     278             :     }
     279        1493 :     jsbytecode* osrPc() const {
     280        1493 :         return osrPc_;
     281             :     }
     282       46179 :     InlineScriptTree* inlineScriptTree() const {
     283       46179 :         return inlineScriptTree_;
     284             :     }
     285             : 
     286             :     bool hasOsrAt(jsbytecode* pc) const {
     287             :         MOZ_ASSERT(JSOp(*pc) == JSOP_LOOPENTRY);
     288             :         return pc == osrPc();
     289             :     }
     290             : 
     291         179 :     jsbytecode* startPC() const {
     292         179 :         return script_->code();
     293             :     }
     294             :     jsbytecode* limitPC() const {
     295             :         return script_->codeEnd();
     296             :     }
     297             : 
     298             :     const char* filename() const {
     299             :         return script_->filename();
     300             :     }
     301             : 
     302             :     unsigned lineno() const {
     303             :         return script_->lineno();
     304             :     }
     305             :     unsigned lineno(jsbytecode* pc) const {
     306             :         return PCToLineNumber(script_, pc);
     307             :     }
     308             : 
     309             :     // Script accessors based on PC.
     310             : 
     311        1623 :     JSAtom* getAtom(jsbytecode* pc) const {
     312        1623 :         return script_->getAtom(GET_UINT32_INDEX(pc));
     313             :     }
     314             : 
     315           3 :     PropertyName* getName(jsbytecode* pc) const {
     316           3 :         return script_->getName(GET_UINT32_INDEX(pc));
     317             :     }
     318             : 
     319             :     inline RegExpObject* getRegExp(jsbytecode* pc) const;
     320             : 
     321           0 :     JSObject* getObject(jsbytecode* pc) const {
     322           0 :         return script_->getObject(GET_UINT32_INDEX(pc));
     323             :     }
     324             : 
     325             :     inline JSFunction* getFunction(jsbytecode* pc) const;
     326             : 
     327          26 :     const Value& getConst(jsbytecode* pc) const {
     328          26 :         return script_->getConst(GET_UINT32_INDEX(pc));
     329             :     }
     330             : 
     331             :     jssrcnote* getNote(GSNCache& gsn, jsbytecode* pc) const {
     332             :         return GetSrcNote(gsn, script(), pc);
     333             :     }
     334             : 
     335             :     // Total number of slots: args, locals, and stack.
     336        7906 :     unsigned nslots() const {
     337        7906 :         return nslots_;
     338             :     }
     339             : 
     340             :     // Number of slots needed for env chain, return value,
     341             :     // maybe argumentsobject and this value.
     342          33 :     unsigned nimplicit() const {
     343          33 :         return nimplicit_;
     344             :     }
     345             :     // Number of arguments (without counting this value).
     346         807 :     unsigned nargs() const {
     347         807 :         return nargs_;
     348             :     }
     349             :     // Number of slots needed for all local variables.  This includes "fixed
     350             :     // vars" (see above) and also block-scoped locals.
     351       47997 :     unsigned nlocals() const {
     352       47997 :         return nlocals_;
     353             :     }
     354         210 :     unsigned ninvoke() const {
     355         210 :         return nslots_ - nstack_;
     356             :     }
     357             : 
     358        5629 :     uint32_t environmentChainSlot() const {
     359        5629 :         MOZ_ASSERT(script());
     360        5629 :         return 0;
     361             :     }
     362         295 :     uint32_t returnValueSlot() const {
     363         295 :         MOZ_ASSERT(script());
     364         295 :         return 1;
     365             :     }
     366        1433 :     uint32_t argsObjSlot() const {
     367        1433 :         MOZ_ASSERT(hasArguments());
     368        1433 :         return 2;
     369             :     }
     370        9024 :     uint32_t thisSlot() const {
     371        9024 :         MOZ_ASSERT(funMaybeLazy());
     372        9024 :         MOZ_ASSERT(nimplicit_ > 0);
     373        9024 :         return nimplicit_ - 1;
     374             :     }
     375        3050 :     uint32_t firstArgSlot() const {
     376        3050 :         return nimplicit_;
     377             :     }
     378         612 :     uint32_t argSlotUnchecked(uint32_t i) const {
     379             :         // During initialization, some routines need to get at arg
     380             :         // slots regardless of how regular argument access is done.
     381         612 :         MOZ_ASSERT(i < nargs_);
     382         612 :         return nimplicit_ + i;
     383             :     }
     384         450 :     uint32_t argSlot(uint32_t i) const {
     385             :         // This should only be accessed when compiling functions for
     386             :         // which argument accesses don't need to go through the
     387             :         // argument object.
     388         450 :         MOZ_ASSERT(!argsObjAliasesFormals());
     389         450 :         return argSlotUnchecked(i);
     390             :     }
     391       66618 :     uint32_t firstLocalSlot() const {
     392       66618 :         return nimplicit_ + nargs_;
     393             :     }
     394        6083 :     uint32_t localSlot(uint32_t i) const {
     395        6083 :         return firstLocalSlot() + i;
     396             :     }
     397       46615 :     uint32_t firstStackSlot() const {
     398       46615 :         return firstLocalSlot() + nlocals();
     399             :     }
     400           0 :     uint32_t stackSlot(uint32_t i) const {
     401           0 :         return firstStackSlot() + i;
     402             :     }
     403             : 
     404         479 :     uint32_t startArgSlot() const {
     405         479 :         MOZ_ASSERT(script());
     406         479 :         return StartArgSlot(script());
     407             :     }
     408        1426 :     uint32_t endArgSlot() const {
     409        1426 :         MOZ_ASSERT(script());
     410        1426 :         return CountArgSlots(script(), funMaybeLazy());
     411             :     }
     412             : 
     413          33 :     uint32_t totalSlots() const {
     414          33 :         MOZ_ASSERT(script() && funMaybeLazy());
     415          33 :         return nimplicit() + nargs() + nlocals();
     416             :     }
     417             : 
     418         225 :     bool isSlotAliased(uint32_t index) const {
     419         225 :         MOZ_ASSERT(index >= startArgSlot());
     420         225 :         uint32_t arg = index - firstArgSlot();
     421         225 :         if (arg < nargs())
     422          39 :             return script()->formalIsAliased(arg);
     423         186 :         return false;
     424             :     }
     425             : 
     426        7083 :     bool hasArguments() const {
     427        7083 :         return script()->argumentsHasVarBinding();
     428             :     }
     429          18 :     bool argumentsAliasesFormals() const {
     430          18 :         return script()->argumentsAliasesFormals();
     431             :     }
     432        3605 :     bool needsArgsObj() const {
     433        3605 :         return scriptNeedsArgsObj_;
     434             :     }
     435         997 :     bool argsObjAliasesFormals() const {
     436         997 :         return scriptNeedsArgsObj_ && script()->hasMappedArgsObj();
     437             :     }
     438             : 
     439        1140 :     AnalysisMode analysisMode() const {
     440        1140 :         return analysisMode_;
     441             :     }
     442             : 
     443        2872 :     bool isAnalysis() const {
     444        2872 :         return analysisMode_ != Analysis_None;
     445             :     }
     446             : 
     447        8657 :     bool needsBodyEnvironmentObject() const {
     448        8657 :         return needsBodyEnvironmentObject_;
     449             :     }
     450             : 
     451             :     // Returns true if a slot can be observed out-side the current frame while
     452             :     // the frame is active on the stack.  This implies that these definitions
     453             :     // would have to be executed and that they cannot be removed even if they
     454             :     // are unused.
     455       13840 :     inline bool isObservableSlot(uint32_t slot) const {
     456       13840 :         if (slot >= firstLocalSlot()) {
     457             :             // The |this| slot for a derived class constructor is a local slot.
     458       11181 :             if (thisSlotForDerivedClassConstructor_)
     459           0 :                 return *thisSlotForDerivedClassConstructor_ == slot;
     460       11181 :             return false;
     461             :         }
     462             : 
     463        2659 :         if (slot < firstArgSlot())
     464        1728 :             return isObservableFrameSlot(slot);
     465             : 
     466         931 :         return isObservableArgumentSlot(slot);
     467             :     }
     468             : 
     469        4700 :     bool isObservableFrameSlot(uint32_t slot) const {
     470             :         // The |envChain| value must be preserved if environments are added
     471             :         // after the prologue.
     472        4700 :         if (needsBodyEnvironmentObject() && slot == environmentChainSlot())
     473           0 :             return true;
     474             : 
     475        4700 :         if (!funMaybeLazy())
     476           0 :             return false;
     477             : 
     478             :         // The |this| value must always be observable.
     479        4700 :         if (slot == thisSlot())
     480         299 :             return true;
     481             : 
     482             :         // The |this| frame slot in derived class constructors should never be
     483             :         // optimized out, as a Debugger might need to perform TDZ checks on it
     484             :         // via, e.g., an exceptionUnwind handler. The TDZ check is required
     485             :         // for correctness if the handler decides to continue execution.
     486        4401 :         if (thisSlotForDerivedClassConstructor_ && *thisSlotForDerivedClassConstructor_ == slot)
     487           0 :             return true;
     488             : 
     489        4401 :         if (funMaybeLazy()->needsSomeEnvironmentObject() && slot == environmentChainSlot())
     490         105 :             return true;
     491             : 
     492             :         // If the function may need an arguments object, then make sure to
     493             :         // preserve the env chain, because it may be needed to construct the
     494             :         // arguments object during bailout. If we've already created an
     495             :         // arguments object (or got one via OSR), preserve that as well.
     496        4296 :         if (hasArguments() && (slot == environmentChainSlot() || slot == argsObjSlot()))
     497          90 :             return true;
     498             : 
     499        4206 :         return false;
     500             :     }
     501             : 
     502         931 :     bool isObservableArgumentSlot(uint32_t slot) const {
     503         931 :         if (!funMaybeLazy())
     504           0 :             return false;
     505             : 
     506             :         // Function.arguments can be used to access all arguments in non-strict
     507             :         // scripts, so we can't optimize out any arguments.
     508        2793 :         if ((hasArguments() || !script()->strict()) &&
     509        1021 :             firstArgSlot() <= slot && slot - firstArgSlot() < nargs())
     510             :         {
     511          45 :             return true;
     512             :         }
     513             : 
     514         886 :         return false;
     515             :     }
     516             : 
     517             :     // Returns true if a slot can be recovered before or during a bailout.  A
     518             :     // definition which can be observed and recovered, implies that this
     519             :     // definition can be optimized away as long as we can compute its values.
     520        3957 :     bool isRecoverableOperand(uint32_t slot) const {
     521             :         // The |envChain| value cannot be recovered if environments can be
     522             :         // added in body (after the prologue).
     523        3957 :         if (needsBodyEnvironmentObject() && slot == environmentChainSlot())
     524           0 :             return false;
     525             : 
     526        3957 :         if (!funMaybeLazy())
     527           0 :             return true;
     528             : 
     529             :         // The |this| and the |envChain| values can be recovered.
     530        3957 :         if (slot == thisSlot() || slot == environmentChainSlot())
     531         985 :             return true;
     532             : 
     533        2972 :         if (isObservableFrameSlot(slot))
     534           0 :             return false;
     535             : 
     536        2972 :         if (needsArgsObj() && isObservableArgumentSlot(slot))
     537           0 :             return false;
     538             : 
     539        2972 :         return true;
     540             :     }
     541             : 
     542             :     // Check previous bailout states to prevent doing the same bailout in the
     543             :     // next compilation.
     544          45 :     bool hadOverflowBailout() const {
     545          45 :         return hadOverflowBailout_;
     546             :     }
     547          13 :     bool mayReadFrameArgsDirectly() const {
     548          13 :         return mayReadFrameArgsDirectly_;
     549             :     }
     550             : 
     551             :   private:
     552             :     unsigned nimplicit_;
     553             :     unsigned nargs_;
     554             :     unsigned nlocals_;
     555             :     unsigned nstack_;
     556             :     unsigned nslots_;
     557             :     mozilla::Maybe<unsigned> thisSlotForDerivedClassConstructor_;
     558             :     JSScript* script_;
     559             :     JSFunction* fun_;
     560             :     jsbytecode* osrPc_;
     561             :     AnalysisMode analysisMode_;
     562             : 
     563             :     // Whether a script needs an arguments object is unstable over compilation
     564             :     // since the arguments optimization could be marked as failed on the active
     565             :     // thread, so cache a value here and use it throughout for consistency.
     566             :     bool scriptNeedsArgsObj_;
     567             : 
     568             :     // Record the state of previous bailouts in order to prevent compiling the
     569             :     // same function identically the next time.
     570             :     bool hadOverflowBailout_;
     571             : 
     572             :     bool mayReadFrameArgsDirectly_;
     573             : 
     574             :     InlineScriptTree* inlineScriptTree_;
     575             : 
     576             :     // Whether a script needs environments within its body. This informs us
     577             :     // that the environment chain is not easy to reconstruct.
     578             :     bool needsBodyEnvironmentObject_;
     579             : };
     580             : 
     581             : } // namespace jit
     582             : } // namespace js
     583             : 
     584             : #endif /* jit_CompileInfo_h */

Generated by: LCOV version 1.13