Sat, 03 Jan 2015 20:18:00 +0100
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.
michael@0 | 1 | /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- |
michael@0 | 2 | * vim: set ts=8 sts=4 et sw=4 tw=99: |
michael@0 | 3 | * This Source Code Form is subject to the terms of the Mozilla Public |
michael@0 | 4 | * License, v. 2.0. If a copy of the MPL was not distributed with this |
michael@0 | 5 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
michael@0 | 6 | |
michael@0 | 7 | #ifndef jit_TypeRepresentationSet_h |
michael@0 | 8 | #define jit_TypeRepresentationSet_h |
michael@0 | 9 | |
michael@0 | 10 | #include "builtin/TypedObject.h" |
michael@0 | 11 | #include "jit/IonAllocPolicy.h" |
michael@0 | 12 | #include "js/HashTable.h" |
michael@0 | 13 | |
michael@0 | 14 | // TypeRepresentationSet stores a set of TypeRepresentation* objects, |
michael@0 | 15 | // representing the possible types of the binary data associated with |
michael@0 | 16 | // a typed object value. Often TypeRepresentationSets will be |
michael@0 | 17 | // singleton sets, but it is also possible to have cases where many |
michael@0 | 18 | // type representations flow into a single point. In such cases, the |
michael@0 | 19 | // various type representations may differ in their details but often |
michael@0 | 20 | // have a common prefix. We try to optimize this case as well. |
michael@0 | 21 | // |
michael@0 | 22 | // So, for example, consider some code like: |
michael@0 | 23 | // |
michael@0 | 24 | // var Point2Type = new StructType({x: uint8, y: uint8}); |
michael@0 | 25 | // var Point3Type = new StructType({x: uint8, y: uint8, z: uint8}); |
michael@0 | 26 | // |
michael@0 | 27 | // function distance2d(pnt) { |
michael@0 | 28 | // return Math.sqrt(pnt.x * pnt.x + pnt.y * pnt.y); |
michael@0 | 29 | // } |
michael@0 | 30 | // |
michael@0 | 31 | // Even if the function `distance2d()` were used with instances of |
michael@0 | 32 | // both Point2Type and Point3Type, we can still generate optimal code, |
michael@0 | 33 | // because both of those types contain fields named `x` and `y` with |
michael@0 | 34 | // the same types at the same offset. |
michael@0 | 35 | |
michael@0 | 36 | namespace js { |
michael@0 | 37 | namespace jit { |
michael@0 | 38 | |
michael@0 | 39 | class IonBuilder; |
michael@0 | 40 | class TypeDescrSet; |
michael@0 | 41 | |
michael@0 | 42 | class TypeDescrSetBuilder { |
michael@0 | 43 | private: |
michael@0 | 44 | Vector<TypeDescr *, 4, SystemAllocPolicy> entries_; |
michael@0 | 45 | bool invalid_; |
michael@0 | 46 | |
michael@0 | 47 | public: |
michael@0 | 48 | TypeDescrSetBuilder(); |
michael@0 | 49 | |
michael@0 | 50 | bool insert(TypeDescr *typeRepr); |
michael@0 | 51 | bool build(IonBuilder &builder, TypeDescrSet *out); |
michael@0 | 52 | }; |
michael@0 | 53 | |
michael@0 | 54 | class TypeDescrSet { |
michael@0 | 55 | private: |
michael@0 | 56 | friend struct TypeDescrSetHasher; |
michael@0 | 57 | friend class TypeDescrSetBuilder; |
michael@0 | 58 | |
michael@0 | 59 | size_t length_; |
michael@0 | 60 | TypeDescr **entries_; // Allocated using temp policy |
michael@0 | 61 | |
michael@0 | 62 | TypeDescrSet(size_t length, TypeDescr **entries); |
michael@0 | 63 | |
michael@0 | 64 | size_t length() const { |
michael@0 | 65 | return length_; |
michael@0 | 66 | } |
michael@0 | 67 | |
michael@0 | 68 | TypeDescr *get(uint32_t i) const { |
michael@0 | 69 | return entries_[i]; |
michael@0 | 70 | } |
michael@0 | 71 | |
michael@0 | 72 | template<typename T> |
michael@0 | 73 | bool genericType(typename T::Type *out); |
michael@0 | 74 | |
michael@0 | 75 | public: |
michael@0 | 76 | ////////////////////////////////////////////////////////////////////// |
michael@0 | 77 | // Constructors |
michael@0 | 78 | // |
michael@0 | 79 | // For more flexible constructors, see |
michael@0 | 80 | // TypeDescrSetBuilder above. |
michael@0 | 81 | |
michael@0 | 82 | TypeDescrSet(const TypeDescrSet &c); |
michael@0 | 83 | TypeDescrSet(); // empty set |
michael@0 | 84 | |
michael@0 | 85 | ////////////////////////////////////////////////////////////////////// |
michael@0 | 86 | // Query the set |
michael@0 | 87 | |
michael@0 | 88 | bool empty() const; |
michael@0 | 89 | bool allOfKind(TypeDescr::Kind kind); |
michael@0 | 90 | |
michael@0 | 91 | // Returns true only when non-empty and `kind()` is |
michael@0 | 92 | // `TypeDescr::Array` |
michael@0 | 93 | bool allOfArrayKind(); |
michael@0 | 94 | |
michael@0 | 95 | // Returns true only if (1) non-empty, (2) for all types t in this |
michael@0 | 96 | // set, t is sized, and (3) there is some size S such that for all |
michael@0 | 97 | // types t in this set, `t.size() == S`. When the above holds, |
michael@0 | 98 | // then also sets `*out` to S; otherwise leaves `*out` unchanged |
michael@0 | 99 | // and returns false. |
michael@0 | 100 | // |
michael@0 | 101 | // At the moment condition (2) trivially holds. When Bug 922115 |
michael@0 | 102 | // lands, some array types will be unsized. |
michael@0 | 103 | bool allHaveSameSize(int32_t *out); |
michael@0 | 104 | |
michael@0 | 105 | types::TemporaryTypeSet *suitableTypeSet(IonBuilder &builder, |
michael@0 | 106 | const Class *knownClass); |
michael@0 | 107 | |
michael@0 | 108 | ////////////////////////////////////////////////////////////////////// |
michael@0 | 109 | // The following operations are only valid on a non-empty set: |
michael@0 | 110 | |
michael@0 | 111 | TypeDescr::Kind kind(); |
michael@0 | 112 | |
michael@0 | 113 | // Returns the prototype that a typed object whose type is within |
michael@0 | 114 | // this TypeDescrSet would have. Returns `null` if this cannot be |
michael@0 | 115 | // predicted or instances of the type are not objects (e.g., uint8). |
michael@0 | 116 | JSObject *knownPrototype() const; |
michael@0 | 117 | |
michael@0 | 118 | ////////////////////////////////////////////////////////////////////// |
michael@0 | 119 | // Scalar operations |
michael@0 | 120 | // |
michael@0 | 121 | // Only valid when `kind() == TypeDescr::Scalar` |
michael@0 | 122 | |
michael@0 | 123 | // If all type descrs in this set have a single type, returns true |
michael@0 | 124 | // and sets *out. Else returns false. |
michael@0 | 125 | bool scalarType(ScalarTypeDescr::Type *out); |
michael@0 | 126 | |
michael@0 | 127 | ////////////////////////////////////////////////////////////////////// |
michael@0 | 128 | // Reference operations |
michael@0 | 129 | // |
michael@0 | 130 | // Only valid when `kind() == TypeDescr::Reference` |
michael@0 | 131 | |
michael@0 | 132 | // If all type descrs in this set have a single type, returns true |
michael@0 | 133 | // and sets *out. Else returns false. |
michael@0 | 134 | bool referenceType(ReferenceTypeDescr::Type *out); |
michael@0 | 135 | |
michael@0 | 136 | ////////////////////////////////////////////////////////////////////// |
michael@0 | 137 | // Reference operations |
michael@0 | 138 | // |
michael@0 | 139 | // Only valid when `kind() == TypeDescr::X4` |
michael@0 | 140 | |
michael@0 | 141 | // If all type descrs in this set have a single type, returns true |
michael@0 | 142 | // and sets *out. Else returns false. |
michael@0 | 143 | bool x4Type(X4TypeDescr::Type *out); |
michael@0 | 144 | |
michael@0 | 145 | ////////////////////////////////////////////////////////////////////// |
michael@0 | 146 | // SizedArray operations |
michael@0 | 147 | // |
michael@0 | 148 | // Only valid when `kind() == TypeDescr::SizedArray` |
michael@0 | 149 | |
michael@0 | 150 | // Determines whether all arrays in this set have the same, |
michael@0 | 151 | // statically known, array length and return that length |
michael@0 | 152 | // (via `*length`) if so. Otherwise returns false. |
michael@0 | 153 | bool hasKnownArrayLength(int32_t *length); |
michael@0 | 154 | |
michael@0 | 155 | // Returns a `TypeDescrSet` representing the element |
michael@0 | 156 | // types of the various array types in this set. The returned set |
michael@0 | 157 | // may be the empty set. |
michael@0 | 158 | bool arrayElementType(IonBuilder &builder, TypeDescrSet *out); |
michael@0 | 159 | |
michael@0 | 160 | ////////////////////////////////////////////////////////////////////// |
michael@0 | 161 | // Struct operations |
michael@0 | 162 | // |
michael@0 | 163 | // Only valid when `kind() == TypeDescr::Struct` |
michael@0 | 164 | |
michael@0 | 165 | // Searches the type in the set for a field named `id`. All |
michael@0 | 166 | // possible types must agree on the offset of the field within the |
michael@0 | 167 | // structure and the possible types of the field must be |
michael@0 | 168 | // compatible. If any pair of types disagree on the offset or have |
michael@0 | 169 | // incompatible types for the field, then `*out` will be set to |
michael@0 | 170 | // the empty set. |
michael@0 | 171 | // |
michael@0 | 172 | // Upon success, `out` will be set to the set of possible types of |
michael@0 | 173 | // the field and `offset` will be set to the field's offset within |
michael@0 | 174 | // the struct (measured in bytes). |
michael@0 | 175 | // |
michael@0 | 176 | // The parameter `*index` is special. If all types agree on the |
michael@0 | 177 | // index of the field, then `*index` is set to the field index. |
michael@0 | 178 | // Otherwise, it is set to SIZE_MAX. Note that two types may agree |
michael@0 | 179 | // on the type and offset of a field but disagree about its index, |
michael@0 | 180 | // e.g. the field `c` in `new StructType({a: uint8, b: uint8, c: |
michael@0 | 181 | // uint16})` and `new StructType({a: uint16, c: uint16})`. |
michael@0 | 182 | bool fieldNamed(IonBuilder &builder, |
michael@0 | 183 | jsid id, |
michael@0 | 184 | int32_t *offset, |
michael@0 | 185 | TypeDescrSet *out, |
michael@0 | 186 | size_t *index); |
michael@0 | 187 | }; |
michael@0 | 188 | |
michael@0 | 189 | struct TypeDescrSetHasher |
michael@0 | 190 | { |
michael@0 | 191 | typedef TypeDescrSet Lookup; |
michael@0 | 192 | static HashNumber hash(TypeDescrSet key); |
michael@0 | 193 | static bool match(TypeDescrSet key1, |
michael@0 | 194 | TypeDescrSet key2); |
michael@0 | 195 | }; |
michael@0 | 196 | |
michael@0 | 197 | typedef js::HashSet<TypeDescrSet, |
michael@0 | 198 | TypeDescrSetHasher, |
michael@0 | 199 | IonAllocPolicy> TypeDescrSetHash; |
michael@0 | 200 | |
michael@0 | 201 | } // namespace jit |
michael@0 | 202 | } // namespace js |
michael@0 | 203 | |
michael@0 | 204 | #endif |