js/src/jit/BaselineFrame.h

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 #ifndef jit_BaselineFrame_h
     8 #define jit_BaselineFrame_h
    10 #ifdef JS_ION
    12 #include "jit/IonFrames.h"
    13 #include "vm/Stack.h"
    15 namespace js {
    16 namespace jit {
    18 struct BaselineDebugModeOSRInfo;
    20 // The stack looks like this, fp is the frame pointer:
    21 //
    22 // fp+y   arguments
    23 // fp+x   IonJSFrameLayout (frame header)
    24 // fp  => saved frame pointer
    25 // fp-x   BaselineFrame
    26 //        locals
    27 //        stack values
    29 // Eval frames
    30 //
    31 // Like js::InterpreterFrame, every BaselineFrame is either a global frame
    32 // or a function frame. Both global and function frames can optionally
    33 // be "eval frames". The callee token for eval function frames is the
    34 // enclosing function. BaselineFrame::evalScript_ stores the eval script
    35 // itself.
    36 class BaselineFrame
    37 {
    38   public:
    39     enum Flags {
    40         // The frame has a valid return value. See also InterpreterFrame::HAS_RVAL.
    41         HAS_RVAL         = 1 << 0,
    43         // A call object has been pushed on the scope chain.
    44         HAS_CALL_OBJ     = 1 << 2,
    46         // Frame has an arguments object, argsObj_.
    47         HAS_ARGS_OBJ     = 1 << 4,
    49         // See InterpreterFrame::PREV_UP_TO_DATE.
    50         PREV_UP_TO_DATE  = 1 << 5,
    52         // Eval frame, see the "eval frames" comment.
    53         EVAL             = 1 << 6,
    55         // Frame has hookData_ set.
    56         HAS_HOOK_DATA    = 1 << 7,
    58         // Frame has profiler entry pushed.
    59         HAS_PUSHED_SPS_FRAME = 1 << 8,
    61         // Frame has over-recursed on an early check.
    62         OVER_RECURSED    = 1 << 9,
    64         // Frame has a BaselineRecompileInfo stashed in the scratch value
    65         // slot. See PatchBaselineFramesForDebugMOde.
    66         HAS_DEBUG_MODE_OSR_INFO = 1 << 10
    67     };
    69   protected: // Silence Clang warning about unused private fields.
    70     // We need to split the Value into 2 fields of 32 bits, otherwise the C++
    71     // compiler may add some padding between the fields.
    72     uint32_t loScratchValue_;
    73     uint32_t hiScratchValue_;
    74     uint32_t loReturnValue_;        // If HAS_RVAL, the frame's return value.
    75     uint32_t hiReturnValue_;
    76     uint32_t frameSize_;
    77     JSObject *scopeChain_;          // Scope chain (always initialized).
    78     JSScript *evalScript_;          // If isEvalFrame(), the current eval script.
    79     ArgumentsObject *argsObj_;      // If HAS_ARGS_OBJ, the arguments object.
    80     void *hookData_;                // If HAS_HOOK_DATA, debugger call hook data.
    81     uint32_t flags_;
    82 #if JS_BITS_PER_WORD == 32
    83     uint32_t padding_;              // Pad to 8-byte alignment.
    84 #endif
    86   public:
    87     // Distance between the frame pointer and the frame header (return address).
    88     // This is the old frame pointer saved in the prologue.
    89     static const uint32_t FramePointerOffset = sizeof(void *);
    91     bool initForOsr(InterpreterFrame *fp, uint32_t numStackValues);
    93     uint32_t frameSize() const {
    94         return frameSize_;
    95     }
    96     void setFrameSize(uint32_t frameSize) {
    97         frameSize_ = frameSize;
    98     }
    99     inline uint32_t *addressOfFrameSize() {
   100         return &frameSize_;
   101     }
   102     JSObject *scopeChain() const {
   103         return scopeChain_;
   104     }
   105     void setScopeChain(JSObject *scopeChain) {
   106         scopeChain_ = scopeChain;
   107     }
   108     inline JSObject **addressOfScopeChain() {
   109         return &scopeChain_;
   110     }
   112     inline Value *addressOfScratchValue() {
   113         return reinterpret_cast<Value *>(&loScratchValue_);
   114     }
   116     inline void pushOnScopeChain(ScopeObject &scope);
   117     inline void popOffScopeChain();
   119     inline void popWith(JSContext *cx);
   121     CalleeToken calleeToken() const {
   122         uint8_t *pointer = (uint8_t *)this + Size() + offsetOfCalleeToken();
   123         return *(CalleeToken *)pointer;
   124     }
   125     void replaceCalleeToken(CalleeToken token) {
   126         uint8_t *pointer = (uint8_t *)this + Size() + offsetOfCalleeToken();
   127         *(CalleeToken *)pointer = token;
   128     }
   129     JSScript *script() const {
   130         if (isEvalFrame())
   131             return evalScript();
   132         return ScriptFromCalleeToken(calleeToken());
   133     }
   134     JSFunction *fun() const {
   135         return CalleeTokenToFunction(calleeToken());
   136     }
   137     JSFunction *maybeFun() const {
   138         return isFunctionFrame() ? fun() : nullptr;
   139     }
   140     JSFunction *callee() const {
   141         return CalleeTokenToFunction(calleeToken());
   142     }
   143     Value calleev() const {
   144         return ObjectValue(*callee());
   145     }
   146     size_t numValueSlots() const {
   147         size_t size = frameSize();
   149         JS_ASSERT(size >= BaselineFrame::FramePointerOffset + BaselineFrame::Size());
   150         size -= BaselineFrame::FramePointerOffset + BaselineFrame::Size();
   152         JS_ASSERT((size % sizeof(Value)) == 0);
   153         return size / sizeof(Value);
   154     }
   155     Value *valueSlot(size_t slot) const {
   156         JS_ASSERT(slot < numValueSlots());
   157         return (Value *)this - (slot + 1);
   158     }
   160     Value &unaliasedVar(uint32_t i, MaybeCheckAliasing checkAliasing = CHECK_ALIASING) const {
   161         JS_ASSERT(i < script()->nfixedvars());
   162         JS_ASSERT_IF(checkAliasing, !script()->varIsAliased(i));
   163         return *valueSlot(i);
   164     }
   166     Value &unaliasedFormal(unsigned i, MaybeCheckAliasing checkAliasing = CHECK_ALIASING) const {
   167         JS_ASSERT(i < numFormalArgs());
   168         JS_ASSERT_IF(checkAliasing, !script()->argsObjAliasesFormals() &&
   169                                     !script()->formalIsAliased(i));
   170         return argv()[i];
   171     }
   173     Value &unaliasedActual(unsigned i, MaybeCheckAliasing checkAliasing = CHECK_ALIASING) const {
   174         JS_ASSERT(i < numActualArgs());
   175         JS_ASSERT_IF(checkAliasing, !script()->argsObjAliasesFormals());
   176         JS_ASSERT_IF(checkAliasing && i < numFormalArgs(), !script()->formalIsAliased(i));
   177         return argv()[i];
   178     }
   180     Value &unaliasedLocal(uint32_t i, MaybeCheckAliasing checkAliasing = CHECK_ALIASING) const {
   181         JS_ASSERT(i < script()->nfixed());
   182 #ifdef DEBUG
   183         CheckLocalUnaliased(checkAliasing, script(), i);
   184 #endif
   185         return *valueSlot(i);
   186     }
   188     unsigned numActualArgs() const {
   189         return *(size_t *)(reinterpret_cast<const uint8_t *>(this) +
   190                              BaselineFrame::Size() +
   191                              offsetOfNumActualArgs());
   192     }
   193     unsigned numFormalArgs() const {
   194         return script()->functionNonDelazifying()->nargs();
   195     }
   196     Value &thisValue() const {
   197         return *(Value *)(reinterpret_cast<const uint8_t *>(this) +
   198                          BaselineFrame::Size() +
   199                          offsetOfThis());
   200     }
   201     Value *argv() const {
   202         return (Value *)(reinterpret_cast<const uint8_t *>(this) +
   203                          BaselineFrame::Size() +
   204                          offsetOfArg(0));
   205     }
   207     bool copyRawFrameSlots(AutoValueVector *vec) const;
   209     bool hasReturnValue() const {
   210         return flags_ & HAS_RVAL;
   211     }
   212     MutableHandleValue returnValue() {
   213         return MutableHandleValue::fromMarkedLocation(reinterpret_cast<Value *>(&loReturnValue_));
   214     }
   215     void setReturnValue(const Value &v) {
   216         flags_ |= HAS_RVAL;
   217         returnValue().set(v);
   218     }
   219     inline Value *addressOfReturnValue() {
   220         return reinterpret_cast<Value *>(&loReturnValue_);
   221     }
   223     bool hasCallObj() const {
   224         return flags_ & HAS_CALL_OBJ;
   225     }
   227     inline CallObject &callObj() const;
   229     void setFlags(uint32_t flags) {
   230         flags_ = flags;
   231     }
   232     uint32_t *addressOfFlags() {
   233         return &flags_;
   234     }
   236     inline bool pushBlock(JSContext *cx, Handle<StaticBlockObject *> block);
   237     inline void popBlock(JSContext *cx);
   239     bool strictEvalPrologue(JSContext *cx);
   240     bool heavyweightFunPrologue(JSContext *cx);
   241     bool initFunctionScopeObjects(JSContext *cx);
   243     void initArgsObjUnchecked(ArgumentsObject &argsobj) {
   244         flags_ |= HAS_ARGS_OBJ;
   245         argsObj_ = &argsobj;
   246     }
   247     void initArgsObj(ArgumentsObject &argsobj) {
   248         JS_ASSERT(script()->needsArgsObj());
   249         initArgsObjUnchecked(argsobj);
   250     }
   251     bool hasArgsObj() const {
   252         return flags_ & HAS_ARGS_OBJ;
   253     }
   254     ArgumentsObject &argsObj() const {
   255         JS_ASSERT(hasArgsObj());
   256         JS_ASSERT(script()->needsArgsObj());
   257         return *argsObj_;
   258     }
   260     bool prevUpToDate() const {
   261         return flags_ & PREV_UP_TO_DATE;
   262     }
   263     void setPrevUpToDate() {
   264         flags_ |= PREV_UP_TO_DATE;
   265     }
   267     JSScript *evalScript() const {
   268         JS_ASSERT(isEvalFrame());
   269         return evalScript_;
   270     }
   272     bool hasHookData() const {
   273         return flags_ & HAS_HOOK_DATA;
   274     }
   276     void *maybeHookData() const {
   277         return hasHookData() ? hookData_ : nullptr;
   278     }
   280     void setHookData(void *v) {
   281         hookData_ = v;
   282         flags_ |= HAS_HOOK_DATA;
   283     }
   285     bool hasPushedSPSFrame() const {
   286         return flags_ & HAS_PUSHED_SPS_FRAME;
   287     }
   289     void setPushedSPSFrame() {
   290         flags_ |= HAS_PUSHED_SPS_FRAME;
   291     }
   293     void unsetPushedSPSFrame() {
   294         flags_ &= ~HAS_PUSHED_SPS_FRAME;
   295     }
   297     bool overRecursed() const {
   298         return flags_ & OVER_RECURSED;
   299     }
   301     void setOverRecursed() {
   302         flags_ |= OVER_RECURSED;
   303     }
   305     BaselineDebugModeOSRInfo *debugModeOSRInfo() {
   306         MOZ_ASSERT(flags_ & HAS_DEBUG_MODE_OSR_INFO);
   307         return *reinterpret_cast<BaselineDebugModeOSRInfo **>(&loScratchValue_);
   308     }
   310     BaselineDebugModeOSRInfo *getDebugModeOSRInfo() {
   311         if (flags_ & HAS_DEBUG_MODE_OSR_INFO)
   312             return debugModeOSRInfo();
   313         return nullptr;
   314     }
   316     void setDebugModeOSRInfo(BaselineDebugModeOSRInfo *info) {
   317         flags_ |= HAS_DEBUG_MODE_OSR_INFO;
   318         *reinterpret_cast<BaselineDebugModeOSRInfo **>(&loScratchValue_) = info;
   319     }
   321     void deleteDebugModeOSRInfo();
   323     void trace(JSTracer *trc, JitFrameIterator &frame);
   325     bool isFunctionFrame() const {
   326         return CalleeTokenIsFunction(calleeToken());
   327     }
   328     bool isGlobalFrame() const {
   329         return !CalleeTokenIsFunction(calleeToken());
   330     }
   331      bool isEvalFrame() const {
   332         return flags_ & EVAL;
   333     }
   334     bool isStrictEvalFrame() const {
   335         return isEvalFrame() && script()->strict();
   336     }
   337     bool isNonStrictEvalFrame() const {
   338         return isEvalFrame() && !script()->strict();
   339     }
   340     bool isDirectEvalFrame() const {
   341         return isEvalFrame() && script()->staticLevel() > 0;
   342     }
   343     bool isNonStrictDirectEvalFrame() const {
   344         return isNonStrictEvalFrame() && isDirectEvalFrame();
   345     }
   346     bool isNonEvalFunctionFrame() const {
   347         return isFunctionFrame() && !isEvalFrame();
   348     }
   349     bool isDebuggerFrame() const {
   350         return false;
   351     }
   352     bool isGeneratorFrame() const {
   353         return false;
   354     }
   356     IonJSFrameLayout *framePrefix() const {
   357         uint8_t *fp = (uint8_t *)this + Size() + FramePointerOffset;
   358         return (IonJSFrameLayout *)fp;
   359     }
   361     // Methods below are used by the compiler.
   362     static size_t offsetOfCalleeToken() {
   363         return FramePointerOffset + js::jit::IonJSFrameLayout::offsetOfCalleeToken();
   364     }
   365     static size_t offsetOfThis() {
   366         return FramePointerOffset + js::jit::IonJSFrameLayout::offsetOfThis();
   367     }
   368     static size_t offsetOfArg(size_t index) {
   369         return FramePointerOffset + js::jit::IonJSFrameLayout::offsetOfActualArg(index);
   370     }
   371     static size_t offsetOfNumActualArgs() {
   372         return FramePointerOffset + js::jit::IonJSFrameLayout::offsetOfNumActualArgs();
   373     }
   374     static size_t Size() {
   375         return sizeof(BaselineFrame);
   376     }
   378     // The reverseOffsetOf methods below compute the offset relative to the
   379     // frame's base pointer. Since the stack grows down, these offsets are
   380     // negative.
   381     static int reverseOffsetOfFrameSize() {
   382         return -int(Size()) + offsetof(BaselineFrame, frameSize_);
   383     }
   384     static int reverseOffsetOfScratchValue() {
   385         return -int(Size()) + offsetof(BaselineFrame, loScratchValue_);
   386     }
   387     static int reverseOffsetOfScopeChain() {
   388         return -int(Size()) + offsetof(BaselineFrame, scopeChain_);
   389     }
   390     static int reverseOffsetOfArgsObj() {
   391         return -int(Size()) + offsetof(BaselineFrame, argsObj_);
   392     }
   393     static int reverseOffsetOfFlags() {
   394         return -int(Size()) + offsetof(BaselineFrame, flags_);
   395     }
   396     static int reverseOffsetOfEvalScript() {
   397         return -int(Size()) + offsetof(BaselineFrame, evalScript_);
   398     }
   399     static int reverseOffsetOfReturnValue() {
   400         return -int(Size()) + offsetof(BaselineFrame, loReturnValue_);
   401     }
   402     static int reverseOffsetOfLocal(size_t index) {
   403         return -int(Size()) - (index + 1) * sizeof(Value);
   404     }
   405 };
   407 // Ensure the frame is 8-byte aligned (required on ARM).
   408 JS_STATIC_ASSERT(((sizeof(BaselineFrame) + BaselineFrame::FramePointerOffset) % 8) == 0);
   410 } // namespace jit
   411 } // namespace js
   413 #endif // JS_ION
   415 #endif /* jit_BaselineFrame_h */

mercurial