js/src/jit/TypeDescrSet.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.

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

mercurial