js/src/jit/BaselineFrame.cpp

Sat, 03 Jan 2015 20:18:00 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Sat, 03 Jan 2015 20:18:00 +0100
branch
TOR_BUG_3246
changeset 7
129ffea94266
permissions
-rw-r--r--

Conditionally enable double key logic according to:
private browsing mode or privacy.thirdparty.isolate preference and
implement in GetCookieStringCommon and FindCookie where it counts...
With some reservations of how to convince FindCookie users to test
condition and pass a nullptr when disabling double key logic.

     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 #include "jit/BaselineFrame-inl.h"
     9 #include "jit/BaselineJIT.h"
    10 #include "jit/Ion.h"
    11 #include "vm/Debugger.h"
    12 #include "vm/ScopeObject.h"
    14 #include "jit/IonFrames-inl.h"
    15 #include "vm/Stack-inl.h"
    17 using namespace js;
    18 using namespace js::jit;
    20 static void
    21 MarkLocals(BaselineFrame *frame, JSTracer *trc, unsigned start, unsigned end)
    22 {
    23     if (start < end) {
    24         // Stack grows down.
    25         Value *last = frame->valueSlot(end - 1);
    26         gc::MarkValueRootRange(trc, end - start, last, "baseline-stack");
    27     }
    28 }
    30 void
    31 BaselineFrame::trace(JSTracer *trc, JitFrameIterator &frameIterator)
    32 {
    33     replaceCalleeToken(MarkCalleeToken(trc, calleeToken()));
    35     gc::MarkValueRoot(trc, &thisValue(), "baseline-this");
    37     // Mark actual and formal args.
    38     if (isNonEvalFunctionFrame()) {
    39         unsigned numArgs = js::Max(numActualArgs(), numFormalArgs());
    40         gc::MarkValueRootRange(trc, numArgs, argv(), "baseline-args");
    41     }
    43     // Mark scope chain, if it exists.
    44     if (scopeChain_)
    45         gc::MarkObjectRoot(trc, &scopeChain_, "baseline-scopechain");
    47     // Mark return value.
    48     if (hasReturnValue())
    49         gc::MarkValueRoot(trc, returnValue().address(), "baseline-rval");
    51     if (isEvalFrame())
    52         gc::MarkScriptRoot(trc, &evalScript_, "baseline-evalscript");
    54     if (hasArgsObj())
    55         gc::MarkObjectRoot(trc, &argsObj_, "baseline-args-obj");
    57     // Mark locals and stack values.
    58     JSScript *script = this->script();
    59     size_t nfixed = script->nfixed();
    60     size_t nlivefixed = script->nfixedvars();
    62     if (nfixed != nlivefixed) {
    63         jsbytecode *pc;
    64         NestedScopeObject *staticScope;
    66         frameIterator.baselineScriptAndPc(nullptr, &pc);
    67         staticScope = script->getStaticScope(pc);
    68         while (staticScope && !staticScope->is<StaticBlockObject>())
    69             staticScope = staticScope->enclosingNestedScope();
    71         if (staticScope) {
    72             StaticBlockObject &blockObj = staticScope->as<StaticBlockObject>();
    73             nlivefixed = blockObj.localOffset() + blockObj.numVariables();
    74         }
    75     }
    77     JS_ASSERT(nlivefixed <= nfixed);
    78     JS_ASSERT(nlivefixed >= script->nfixedvars());
    80     // NB: It is possible that numValueSlots() could be zero, even if nfixed is
    81     // nonzero.  This is the case if the function has an early stack check.
    82     if (numValueSlots() == 0)
    83         return;
    85     JS_ASSERT(nfixed <= numValueSlots());
    87     if (nfixed == nlivefixed) {
    88         // All locals are live.
    89         MarkLocals(this, trc, 0, numValueSlots());
    90     } else {
    91         // Mark operand stack.
    92         MarkLocals(this, trc, nfixed, numValueSlots());
    94         // Clear dead locals.
    95         while (nfixed > nlivefixed)
    96             unaliasedLocal(--nfixed, DONT_CHECK_ALIASING).setUndefined();
    98         // Mark live locals.
    99         MarkLocals(this, trc, 0, nlivefixed);
   100     }
   101 }
   103 bool
   104 BaselineFrame::copyRawFrameSlots(AutoValueVector *vec) const
   105 {
   106     unsigned nfixed = script()->nfixed();
   107     unsigned nformals = numFormalArgs();
   109     if (!vec->resize(nformals + nfixed))
   110         return false;
   112     mozilla::PodCopy(vec->begin(), argv(), nformals);
   113     for (unsigned i = 0; i < nfixed; i++)
   114         (*vec)[nformals + i] = *valueSlot(i);
   115     return true;
   116 }
   118 bool
   119 BaselineFrame::strictEvalPrologue(JSContext *cx)
   120 {
   121     JS_ASSERT(isStrictEvalFrame());
   123     CallObject *callobj = CallObject::createForStrictEval(cx, this);
   124     if (!callobj)
   125         return false;
   127     pushOnScopeChain(*callobj);
   128     flags_ |= HAS_CALL_OBJ;
   129     return true;
   130 }
   132 bool
   133 BaselineFrame::heavyweightFunPrologue(JSContext *cx)
   134 {
   135     return initFunctionScopeObjects(cx);
   136 }
   138 bool
   139 BaselineFrame::initFunctionScopeObjects(JSContext *cx)
   140 {
   141     JS_ASSERT(isNonEvalFunctionFrame());
   142     JS_ASSERT(fun()->isHeavyweight());
   144     CallObject *callobj = CallObject::createForFunction(cx, this);
   145     if (!callobj)
   146         return false;
   148     pushOnScopeChain(*callobj);
   149     flags_ |= HAS_CALL_OBJ;
   150     return true;
   151 }
   153 bool
   154 BaselineFrame::initForOsr(InterpreterFrame *fp, uint32_t numStackValues)
   155 {
   156     mozilla::PodZero(this);
   158     scopeChain_ = fp->scopeChain();
   160     if (fp->hasCallObjUnchecked())
   161         flags_ |= BaselineFrame::HAS_CALL_OBJ;
   163     if (fp->isEvalFrame()) {
   164         flags_ |= BaselineFrame::EVAL;
   165         evalScript_ = fp->script();
   166     }
   168     if (fp->script()->needsArgsObj() && fp->hasArgsObj()) {
   169         flags_ |= BaselineFrame::HAS_ARGS_OBJ;
   170         argsObj_ = &fp->argsObj();
   171     }
   173     if (fp->hasHookData()) {
   174         flags_ |= BaselineFrame::HAS_HOOK_DATA;
   175         hookData_ = fp->hookData();
   176     }
   178     if (fp->hasReturnValue())
   179         setReturnValue(fp->returnValue());
   181     // If the interpreter pushed an SPS frame when it entered the function, the
   182     // interpreter will pop it after the OSR trampoline returns.  In order for
   183     // the Baseline frame to have its SPS flag set, it must have its own SPS
   184     // frame, which the Baseline code will pop on return.  Note that the
   185     // profiler may have been enabled or disabled after the function was entered
   186     // but before OSR.
   187     JSContext *cx = GetJSContextFromJitCode();
   188     SPSProfiler *p = &(cx->runtime()->spsProfiler);
   189     if (p->enabled()) {
   190         p->enter(fp->script(), fp->maybeFun());
   191         flags_ |= BaselineFrame::HAS_PUSHED_SPS_FRAME;
   192     }
   194     frameSize_ = BaselineFrame::FramePointerOffset +
   195         BaselineFrame::Size() +
   196         numStackValues * sizeof(Value);
   198     JS_ASSERT(numValueSlots() == numStackValues);
   200     for (uint32_t i = 0; i < numStackValues; i++)
   201         *valueSlot(i) = fp->slots()[i];
   203     if (cx->compartment()->debugMode()) {
   204         // In debug mode, update any Debugger.Frame objects for the
   205         // InterpreterFrame to point to the BaselineFrame.
   207         // The caller pushed a fake return address. ScriptFrameIter, used by the
   208         // debugger, wants a valid return address, but it's okay to just pick one.
   209         // In debug mode there's always at least 1 ICEntry (since there are always
   210         // debug prologue/epilogue calls).
   211         JitFrameIterator iter(cx);
   212         JS_ASSERT(iter.returnAddress() == nullptr);
   213         BaselineScript *baseline = fp->script()->baselineScript();
   214         iter.current()->setReturnAddress(baseline->returnAddressForIC(baseline->icEntry(0)));
   216         if (!Debugger::handleBaselineOsr(cx, fp, this))
   217             return false;
   218     }
   220     return true;
   221 }

mercurial