js/src/vm/PIC.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 vm_PIC_h
     8 #define vm_PIC_h
    10 #include "jsapi.h"
    11 #include "jscntxt.h"
    12 #include "jsfriendapi.h"
    13 #include "jsobj.h"
    15 #include "gc/Barrier.h"
    16 #include "gc/Heap.h"
    17 #include "gc/Marking.h"
    19 #include "js/Value.h"
    20 #include "vm/GlobalObject.h"
    22 namespace js {
    24 class Shape;
    26 template <typename Category> class PICChain;
    28 /*
    29  * The basic PICStub just has a pointer to the next stub.
    30  */
    31 template <typename Category>
    32 class PICStub
    33 {
    34   friend class PICChain<Category>;
    35   private:
    36     typedef typename Category::Stub CatStub;
    37     typedef typename Category::Chain CatChain;
    39   protected:
    40     CatStub *next_;
    42     PICStub() : next_(nullptr) {}
    43     PICStub(const CatStub *next) : next_(next) {
    44         JS_ASSERT(next_);
    45     }
    46     PICStub(const CatStub &other) : next_(other.next_) {}
    48   public:
    49     CatStub *next() const {
    50         return next_;
    51     }
    53   protected:
    54     void append(CatStub *stub) {
    55         JS_ASSERT(!next_);
    56         JS_ASSERT(!stub->next_);
    57         next_ = stub;
    58     }
    59 };
    61 /*
    62  * The basic PIC just has a pointer to the list of stubs.
    63  */
    64 template <typename Category>
    65 class PICChain
    66 {
    67   private:
    68     typedef typename Category::Stub CatStub;
    69     typedef typename Category::Chain CatChain;
    71   protected:
    72     CatStub *stubs_;
    74     PICChain() : stubs_(nullptr) {}
    75     // PICs should never be copy constructed.
    76     PICChain(const PICChain<Category> &other) MOZ_DELETE;
    78   public:
    79     CatStub *stubs() const {
    80         return stubs_;
    81     }
    83     void addStub(CatStub *stub) {
    84         JS_ASSERT(stub);
    85         JS_ASSERT(!stub->next());
    86         if (!stubs_) {
    87             stubs_ = stub;
    88             return;
    89         }
    91         CatStub *cur = stubs_;
    92         while (cur->next())
    93             cur = cur->next();
    94         cur->append(stub);
    95     }
    97     unsigned numStubs() const {
    98         unsigned count = 0;
    99         for (CatStub *stub = stubs_; stub; stub = stub->next())
   100             count++;
   101         return count;
   102     }
   104     void removeStub(CatStub *stub, CatStub *previous) {
   105         if (previous) {
   106             JS_ASSERT(previous->next() == stub);
   107             previous->next_ = stub->next();
   108         } else {
   109             JS_ASSERT(stub == stubs_);
   110             stubs_ = stub->next();
   111         }
   112         js_delete(stub);
   113     }
   114 };
   116 /*
   117  *  ForOfPIC defines a PIC category for optimizing for-of operations.
   118  */
   119 struct ForOfPIC
   120 {
   121     /* Forward declarations so template-substitution works. */
   122     class Stub;
   123     class Chain;
   125     ForOfPIC() MOZ_DELETE;
   126     ForOfPIC(const ForOfPIC &other) MOZ_DELETE;
   128     typedef PICStub<ForOfPIC> BaseStub;
   129     typedef PICChain<ForOfPIC> BaseChain;
   131     /*
   132      * A ForOfPIC has only one kind of stub for now: one that holds the shape
   133      * of an array object that does not override its '@@iterator' property.
   134      */
   135     class Stub : public BaseStub
   136     {
   137       private:
   138         // Shape of matching array object.
   139         Shape *shape_;
   141       public:
   142         Stub(Shape *shape)
   143           : BaseStub(),
   144             shape_(shape)
   145         {
   146             JS_ASSERT(shape_);
   147         }
   149         Shape *shape() {
   150             return shape_;
   151         }
   152     };
   154     /*
   155      * A ForOfPIC chain holds the following:
   156      *
   157      *  Array.prototype (arrayProto_)
   158      *      To ensure that the incoming array has the standard proto.
   159      *
   160      *  Array.prototype's shape (arrayProtoShape_)
   161      *      To ensure that Array.prototype has not been modified.
   162      *
   163      *  ArrayIterator.prototype (arrayIteratorProto_)
   164      *  ArrayIterator.prototype's shape (arrayIteratorProtoShape_)
   165      *      To ensure that an ArrayIterator.prototype has not been modified.
   166      *
   167      *  Array.prototype's slot number for '@@iterator' (arrayProtoIteratorSlot_)
   168      *  Array.prototype's canonical value for '@@iterator' (canonicalIteratorFunc_)
   169      *      To quickly retreive and ensure that the iterator constructor
   170      *      stored in the slot has not changed.
   171      *
   172      *  ArrayIterator.prototype's slot number for 'next' (arrayIteratorProtoNextSlot_)
   173      *  ArrayIterator.prototype's canonical value for 'next' (canonicalNextFunc_)
   174      *      To quickly retreive and ensure that the 'next' method for ArrayIterator
   175      *      objects has not changed.
   176      */
   177     class Chain : public BaseChain
   178     {
   179       private:
   180         // Pointer to canonical Array.prototype and ArrayIterator.prototype
   181         HeapPtrObject arrayProto_;
   182         HeapPtrObject arrayIteratorProto_;
   184         // Shape of matching Array.prototype object, and slot containing
   185         // the '@@iterator' for it, and the canonical value.
   186         HeapPtrShape arrayProtoShape_;
   187         uint32_t arrayProtoIteratorSlot_;
   188         HeapValue canonicalIteratorFunc_;
   190         // Shape of matching ArrayIteratorProto, and slot containing
   191         // the 'next' property, and the canonical value.
   192         HeapPtrShape arrayIteratorProtoShape_;
   193         uint32_t arrayIteratorProtoNextSlot_;
   194         HeapValue canonicalNextFunc_;
   196         // Initialization flag marking lazy initialization of above fields.
   197         bool initialized_;
   199         // Disabled flag is set when we don't want to try optimizing anymore
   200         // because core objects were changed.
   201         bool disabled_;
   203         static const unsigned MAX_STUBS = 10;
   205       public:
   206         Chain()
   207           : BaseChain(),
   208             arrayProto_(nullptr),
   209             arrayIteratorProto_(nullptr),
   210             arrayProtoShape_(nullptr),
   211             arrayProtoIteratorSlot_(-1),
   212             canonicalIteratorFunc_(UndefinedValue()),
   213             arrayIteratorProtoShape_(nullptr),
   214             arrayIteratorProtoNextSlot_(-1),
   215             initialized_(false),
   216             disabled_(false)
   217         {}
   219         // Initialize the canonical iterator function.
   220         bool initialize(JSContext *cx);
   222         // Check if a given array object is optimized by this PIC.
   223         Stub *isArrayOptimized(ArrayObject *obj);
   225         // Try to optimize this chain for an object.
   226         bool tryOptimizeArray(JSContext *cx, HandleObject array, bool *optimized);
   228         // Check if the global array-related objects have not been messed with
   229         // in a way that would disable this PIC.
   230         bool isArrayStateStillSane();
   232         // Check if ArrayIterator.next is still optimizable.
   233         inline bool isArrayNextStillSane() {
   234             return (arrayIteratorProto_->lastProperty() == arrayIteratorProtoShape_) &&
   235                 (arrayIteratorProto_->getSlot(arrayIteratorProtoNextSlot_) == canonicalNextFunc_);
   236         }
   238         void mark(JSTracer *trc);
   239         void sweep(FreeOp *fop);
   241       private:
   242         // Get a matching optimized stub for the given object.
   243         Stub *getMatchingStub(JSObject *obj);
   245         // Check if the given object is for-of optimizable with this PIC.
   246         bool isOptimizableArray(JSObject *obj);
   248         // Reset the PIC and all info associated with it.
   249         void reset(JSContext *cx);
   251         // Erase the stub chain.
   252         void eraseChain();
   253     };
   255     // Class for object that holds ForOfPIC chain.
   256     static const Class jsclass;
   258     static JSObject *createForOfPICObject(JSContext *cx, Handle<GlobalObject *> global);
   260     static inline Chain *fromJSObject(JSObject *obj) {
   261         JS_ASSERT(js::GetObjectClass(obj) == &ForOfPIC::jsclass);
   262         return (ForOfPIC::Chain *) obj->getPrivate();
   263     }
   264     static inline Chain *getOrCreate(JSContext *cx) {
   265         JSObject *obj = cx->global()->getForOfPICObject();
   266         if (obj)
   267             return fromJSObject(obj);
   268         return create(cx);
   269     }
   270     static Chain *create(JSContext *cx);
   271 };
   274 } // namespace js
   276 #endif /* vm_PIC_h */

mercurial