js/src/jit/CompileInfo.h

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

     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/. */
     7 #ifndef jit_CompileInfo_h
     8 #define jit_CompileInfo_h
    10 #include "jsfun.h"
    12 #include "jit/Registers.h"
    13 #include "vm/ScopeObject.h"
    15 namespace js {
    16 namespace jit {
    18 inline unsigned
    19 StartArgSlot(JSScript *script)
    20 {
    21     // Reserved slots:
    22     // Slot 0: Scope chain.
    23     // Slot 1: Return value.
    25     // When needed:
    26     // Slot 2: Argumentsobject.
    28     // Note: when updating this, please also update the assert in SnapshotWriter::startFrame
    29     return 2 + (script->argumentsHasVarBinding() ? 1 : 0);
    30 }
    32 inline unsigned
    33 CountArgSlots(JSScript *script, JSFunction *fun)
    34 {
    35     // Slot x + 0: This value.
    36     // Slot x + 1: Argument 1.
    37     // ...
    38     // Slot x + n: Argument n.
    40     // Note: when updating this, please also update the assert in SnapshotWriter::startFrame
    41     return StartArgSlot(script) + (fun ? fun->nargs() + 1 : 0);
    42 }
    44 // Contains information about the compilation source for IR being generated.
    45 class CompileInfo
    46 {
    47   public:
    48     CompileInfo(JSScript *script, JSFunction *fun, jsbytecode *osrPc, bool constructing,
    49                 ExecutionMode executionMode, bool scriptNeedsArgsObj)
    50       : script_(script), fun_(fun), osrPc_(osrPc), constructing_(constructing),
    51         executionMode_(executionMode), scriptNeedsArgsObj_(scriptNeedsArgsObj)
    52     {
    53         JS_ASSERT_IF(osrPc, JSOp(*osrPc) == JSOP_LOOPENTRY);
    55         // The function here can flow in from anywhere so look up the canonical
    56         // function to ensure that we do not try to embed a nursery pointer in
    57         // jit-code. Precisely because it can flow in from anywhere, it's not
    58         // guaranteed to be non-lazy. Hence, don't access its script!
    59         if (fun_) {
    60             fun_ = fun_->nonLazyScript()->functionNonDelazifying();
    61             JS_ASSERT(fun_->isTenured());
    62         }
    64         osrStaticScope_ = osrPc ? script->getStaticScope(osrPc) : nullptr;
    66         nimplicit_ = StartArgSlot(script)                   /* scope chain and argument obj */
    67                    + (fun ? 1 : 0);                         /* this */
    68         nargs_ = fun ? fun->nargs() : 0;
    69         nfixedvars_ = script->nfixedvars();
    70         nlocals_ = script->nfixed();
    71         nstack_ = script->nslots() - script->nfixed();
    72         nslots_ = nimplicit_ + nargs_ + nlocals_ + nstack_;
    73     }
    75     CompileInfo(unsigned nlocals, ExecutionMode executionMode)
    76       : script_(nullptr), fun_(nullptr), osrPc_(nullptr), osrStaticScope_(nullptr),
    77         constructing_(false), executionMode_(executionMode), scriptNeedsArgsObj_(false)
    78     {
    79         nimplicit_ = 0;
    80         nargs_ = 0;
    81         nfixedvars_ = 0;
    82         nlocals_ = nlocals;
    83         nstack_ = 1;  /* For FunctionCompiler::pushPhiInput/popPhiOutput */
    84         nslots_ = nlocals_ + nstack_;
    85     }
    87     JSScript *script() const {
    88         return script_;
    89     }
    90     JSFunction *funMaybeLazy() const {
    91         return fun_;
    92     }
    93     bool constructing() const {
    94         return constructing_;
    95     }
    96     jsbytecode *osrPc() {
    97         return osrPc_;
    98     }
    99     NestedScopeObject *osrStaticScope() const {
   100         return osrStaticScope_;
   101     }
   103     bool hasOsrAt(jsbytecode *pc) {
   104         JS_ASSERT(JSOp(*pc) == JSOP_LOOPENTRY);
   105         return pc == osrPc();
   106     }
   108     jsbytecode *startPC() const {
   109         return script_->code();
   110     }
   111     jsbytecode *limitPC() const {
   112         return script_->codeEnd();
   113     }
   115     const char *filename() const {
   116         return script_->filename();
   117     }
   119     unsigned lineno() const {
   120         return script_->lineno();
   121     }
   122     unsigned lineno(jsbytecode *pc) const {
   123         return PCToLineNumber(script_, pc);
   124     }
   126     // Script accessors based on PC.
   128     JSAtom *getAtom(jsbytecode *pc) const {
   129         return script_->getAtom(GET_UINT32_INDEX(pc));
   130     }
   132     PropertyName *getName(jsbytecode *pc) const {
   133         return script_->getName(GET_UINT32_INDEX(pc));
   134     }
   136     inline RegExpObject *getRegExp(jsbytecode *pc) const;
   138     JSObject *getObject(jsbytecode *pc) const {
   139         return script_->getObject(GET_UINT32_INDEX(pc));
   140     }
   142     inline JSFunction *getFunction(jsbytecode *pc) const;
   144     const Value &getConst(jsbytecode *pc) const {
   145         return script_->getConst(GET_UINT32_INDEX(pc));
   146     }
   148     jssrcnote *getNote(GSNCache &gsn, jsbytecode *pc) const {
   149         return GetSrcNote(gsn, script(), pc);
   150     }
   152     // Total number of slots: args, locals, and stack.
   153     unsigned nslots() const {
   154         return nslots_;
   155     }
   157     // Number of slots needed for Scope chain, return value,
   158     // maybe argumentsobject and this value.
   159     unsigned nimplicit() const {
   160         return nimplicit_;
   161     }
   162     // Number of arguments (without counting this value).
   163     unsigned nargs() const {
   164         return nargs_;
   165     }
   166     // Number of slots needed for "fixed vars".  Note that this is only non-zero
   167     // for function code.
   168     unsigned nfixedvars() const {
   169         return nfixedvars_;
   170     }
   171     // Number of slots needed for all local variables.  This includes "fixed
   172     // vars" (see above) and also block-scoped locals.
   173     unsigned nlocals() const {
   174         return nlocals_;
   175     }
   176     unsigned ninvoke() const {
   177         return nslots_ - nstack_;
   178     }
   180     uint32_t scopeChainSlot() const {
   181         JS_ASSERT(script());
   182         return 0;
   183     }
   184     uint32_t returnValueSlot() const {
   185         JS_ASSERT(script());
   186         return 1;
   187     }
   188     uint32_t argsObjSlot() const {
   189         JS_ASSERT(hasArguments());
   190         return 2;
   191     }
   192     uint32_t thisSlot() const {
   193         JS_ASSERT(funMaybeLazy());
   194         JS_ASSERT(nimplicit_ > 0);
   195         return nimplicit_ - 1;
   196     }
   197     uint32_t firstArgSlot() const {
   198         return nimplicit_;
   199     }
   200     uint32_t argSlotUnchecked(uint32_t i) const {
   201         // During initialization, some routines need to get at arg
   202         // slots regardless of how regular argument access is done.
   203         JS_ASSERT(i < nargs_);
   204         return nimplicit_ + i;
   205     }
   206     uint32_t argSlot(uint32_t i) const {
   207         // This should only be accessed when compiling functions for
   208         // which argument accesses don't need to go through the
   209         // argument object.
   210         JS_ASSERT(!argsObjAliasesFormals());
   211         return argSlotUnchecked(i);
   212     }
   213     uint32_t firstLocalSlot() const {
   214         return nimplicit_ + nargs_;
   215     }
   216     uint32_t localSlot(uint32_t i) const {
   217         return firstLocalSlot() + i;
   218     }
   219     uint32_t firstStackSlot() const {
   220         return firstLocalSlot() + nlocals();
   221     }
   222     uint32_t stackSlot(uint32_t i) const {
   223         return firstStackSlot() + i;
   224     }
   226     uint32_t startArgSlot() const {
   227         JS_ASSERT(script());
   228         return StartArgSlot(script());
   229     }
   230     uint32_t endArgSlot() const {
   231         JS_ASSERT(script());
   232         return CountArgSlots(script(), funMaybeLazy());
   233     }
   235     uint32_t totalSlots() const {
   236         JS_ASSERT(script() && funMaybeLazy());
   237         return nimplicit() + nargs() + nlocals();
   238     }
   240     bool isSlotAliased(uint32_t index, NestedScopeObject *staticScope) const {
   241         JS_ASSERT(index >= startArgSlot());
   243         if (funMaybeLazy() && index == thisSlot())
   244             return false;
   246         uint32_t arg = index - firstArgSlot();
   247         if (arg < nargs())
   248             return script()->formalIsAliased(arg);
   250         uint32_t local = index - firstLocalSlot();
   251         if (local < nlocals()) {
   252             // First, check if this local is a var.
   253             if (local < nfixedvars())
   254                 return script()->varIsAliased(local);
   256             // Otherwise, it might be part of a block scope.
   257             for (; staticScope; staticScope = staticScope->enclosingNestedScope()) {
   258                 if (!staticScope->is<StaticBlockObject>())
   259                     continue;
   260                 StaticBlockObject &blockObj = staticScope->as<StaticBlockObject>();
   261                 if (blockObj.localOffset() < local) {
   262                     if (local - blockObj.localOffset() < blockObj.numVariables())
   263                         return blockObj.isAliased(local - blockObj.localOffset());
   264                     return false;
   265                 }
   266             }
   268             // In this static scope, this var is dead.
   269             return false;
   270         }
   272         JS_ASSERT(index >= firstStackSlot());
   273         return false;
   274     }
   276     bool isSlotAliasedAtEntry(uint32_t index) const {
   277         return isSlotAliased(index, nullptr);
   278     }
   279     bool isSlotAliasedAtOsr(uint32_t index) const {
   280         return isSlotAliased(index, osrStaticScope());
   281     }
   283     bool hasArguments() const {
   284         return script()->argumentsHasVarBinding();
   285     }
   286     bool argumentsAliasesFormals() const {
   287         return script()->argumentsAliasesFormals();
   288     }
   289     bool needsArgsObj() const {
   290         return scriptNeedsArgsObj_;
   291     }
   292     bool argsObjAliasesFormals() const {
   293         return scriptNeedsArgsObj_ && !script()->strict();
   294     }
   296     ExecutionMode executionMode() const {
   297         return executionMode_;
   298     }
   300     bool executionModeIsAnalysis() const {
   301         return executionMode_ == DefinitePropertiesAnalysis || executionMode_ == ArgumentsUsageAnalysis;
   302     }
   304     bool isParallelExecution() const {
   305         return executionMode_ == ParallelExecution;
   306     }
   308     bool canOptimizeOutSlot(uint32_t i) const {
   309         if (script()->strict())
   310             return true;
   312         // Function.arguments can be used to access all arguments in
   313         // non-strict scripts, so we can't optimize out any arguments.
   314         return !(firstArgSlot() <= i && i - firstArgSlot() < nargs());
   315     }
   317   private:
   318     unsigned nimplicit_;
   319     unsigned nargs_;
   320     unsigned nfixedvars_;
   321     unsigned nlocals_;
   322     unsigned nstack_;
   323     unsigned nslots_;
   324     JSScript *script_;
   325     JSFunction *fun_;
   326     jsbytecode *osrPc_;
   327     NestedScopeObject *osrStaticScope_;
   328     bool constructing_;
   329     ExecutionMode executionMode_;
   331     // Whether a script needs an arguments object is unstable over compilation
   332     // since the arguments optimization could be marked as failed on the main
   333     // thread, so cache a value here and use it throughout for consistency.
   334     bool scriptNeedsArgsObj_;
   335 };
   337 } // namespace jit
   338 } // namespace js
   340 #endif /* jit_CompileInfo_h */

mercurial