js/src/jit/TypeDescrSet.h

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/js/src/jit/TypeDescrSet.h	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,204 @@
     1.4 +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
     1.5 + * vim: set ts=8 sts=4 et sw=4 tw=99:
     1.6 + * This Source Code Form is subject to the terms of the Mozilla Public
     1.7 + * License, v. 2.0. If a copy of the MPL was not distributed with this
     1.8 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     1.9 +
    1.10 +#ifndef jit_TypeRepresentationSet_h
    1.11 +#define jit_TypeRepresentationSet_h
    1.12 +
    1.13 +#include "builtin/TypedObject.h"
    1.14 +#include "jit/IonAllocPolicy.h"
    1.15 +#include "js/HashTable.h"
    1.16 +
    1.17 +// TypeRepresentationSet stores a set of TypeRepresentation* objects,
    1.18 +// representing the possible types of the binary data associated with
    1.19 +// a typed object value.  Often TypeRepresentationSets will be
    1.20 +// singleton sets, but it is also possible to have cases where many
    1.21 +// type representations flow into a single point. In such cases, the
    1.22 +// various type representations may differ in their details but often
    1.23 +// have a common prefix. We try to optimize this case as well.
    1.24 +//
    1.25 +// So, for example, consider some code like:
    1.26 +//
    1.27 +//     var Point2Type = new StructType({x: uint8, y: uint8});
    1.28 +//     var Point3Type = new StructType({x: uint8, y: uint8, z: uint8});
    1.29 +//
    1.30 +//     function distance2d(pnt) {
    1.31 +//         return Math.sqrt(pnt.x * pnt.x + pnt.y * pnt.y);
    1.32 +//     }
    1.33 +//
    1.34 +// Even if the function `distance2d()` were used with instances of
    1.35 +// both Point2Type and Point3Type, we can still generate optimal code,
    1.36 +// because both of those types contain fields named `x` and `y` with
    1.37 +// the same types at the same offset.
    1.38 +
    1.39 +namespace js {
    1.40 +namespace jit {
    1.41 +
    1.42 +class IonBuilder;
    1.43 +class TypeDescrSet;
    1.44 +
    1.45 +class TypeDescrSetBuilder {
    1.46 +  private:
    1.47 +    Vector<TypeDescr *, 4, SystemAllocPolicy> entries_;
    1.48 +    bool invalid_;
    1.49 +
    1.50 +  public:
    1.51 +    TypeDescrSetBuilder();
    1.52 +
    1.53 +    bool insert(TypeDescr *typeRepr);
    1.54 +    bool build(IonBuilder &builder, TypeDescrSet *out);
    1.55 +};
    1.56 +
    1.57 +class TypeDescrSet {
    1.58 +  private:
    1.59 +    friend struct TypeDescrSetHasher;
    1.60 +    friend class TypeDescrSetBuilder;
    1.61 +
    1.62 +    size_t length_;
    1.63 +    TypeDescr **entries_; // Allocated using temp policy
    1.64 +
    1.65 +    TypeDescrSet(size_t length, TypeDescr **entries);
    1.66 +
    1.67 +    size_t length() const {
    1.68 +        return length_;
    1.69 +    }
    1.70 +
    1.71 +    TypeDescr *get(uint32_t i) const {
    1.72 +        return entries_[i];
    1.73 +    }
    1.74 +
    1.75 +    template<typename T>
    1.76 +    bool genericType(typename T::Type *out);
    1.77 +
    1.78 +  public:
    1.79 +    //////////////////////////////////////////////////////////////////////
    1.80 +    // Constructors
    1.81 +    //
    1.82 +    // For more flexible constructors, see
    1.83 +    // TypeDescrSetBuilder above.
    1.84 +
    1.85 +    TypeDescrSet(const TypeDescrSet &c);
    1.86 +    TypeDescrSet(); // empty set
    1.87 +
    1.88 +    //////////////////////////////////////////////////////////////////////
    1.89 +    // Query the set
    1.90 +
    1.91 +    bool empty() const;
    1.92 +    bool allOfKind(TypeDescr::Kind kind);
    1.93 +
    1.94 +    // Returns true only when non-empty and `kind()` is
    1.95 +    // `TypeDescr::Array`
    1.96 +    bool allOfArrayKind();
    1.97 +
    1.98 +    // Returns true only if (1) non-empty, (2) for all types t in this
    1.99 +    // set, t is sized, and (3) there is some size S such that for all
   1.100 +    // types t in this set, `t.size() == S`.  When the above holds,
   1.101 +    // then also sets `*out` to S; otherwise leaves `*out` unchanged
   1.102 +    // and returns false.
   1.103 +    //
   1.104 +    // At the moment condition (2) trivially holds.  When Bug 922115
   1.105 +    // lands, some array types will be unsized.
   1.106 +    bool allHaveSameSize(int32_t *out);
   1.107 +
   1.108 +    types::TemporaryTypeSet *suitableTypeSet(IonBuilder &builder,
   1.109 +                                             const Class *knownClass);
   1.110 +
   1.111 +    //////////////////////////////////////////////////////////////////////
   1.112 +    // The following operations are only valid on a non-empty set:
   1.113 +
   1.114 +    TypeDescr::Kind kind();
   1.115 +
   1.116 +    // Returns the prototype that a typed object whose type is within
   1.117 +    // this TypeDescrSet would have. Returns `null` if this cannot be
   1.118 +    // predicted or instances of the type are not objects (e.g., uint8).
   1.119 +    JSObject *knownPrototype() const;
   1.120 +
   1.121 +    //////////////////////////////////////////////////////////////////////
   1.122 +    // Scalar operations
   1.123 +    //
   1.124 +    // Only valid when `kind() == TypeDescr::Scalar`
   1.125 +
   1.126 +    // If all type descrs in this set have a single type, returns true
   1.127 +    // and sets *out. Else returns false.
   1.128 +    bool scalarType(ScalarTypeDescr::Type *out);
   1.129 +
   1.130 +    //////////////////////////////////////////////////////////////////////
   1.131 +    // Reference operations
   1.132 +    //
   1.133 +    // Only valid when `kind() == TypeDescr::Reference`
   1.134 +
   1.135 +    // If all type descrs in this set have a single type, returns true
   1.136 +    // and sets *out. Else returns false.
   1.137 +    bool referenceType(ReferenceTypeDescr::Type *out);
   1.138 +
   1.139 +    //////////////////////////////////////////////////////////////////////
   1.140 +    // Reference operations
   1.141 +    //
   1.142 +    // Only valid when `kind() == TypeDescr::X4`
   1.143 +
   1.144 +    // If all type descrs in this set have a single type, returns true
   1.145 +    // and sets *out. Else returns false.
   1.146 +    bool x4Type(X4TypeDescr::Type *out);
   1.147 +
   1.148 +    //////////////////////////////////////////////////////////////////////
   1.149 +    // SizedArray operations
   1.150 +    //
   1.151 +    // Only valid when `kind() == TypeDescr::SizedArray`
   1.152 +
   1.153 +    // Determines whether all arrays in this set have the same,
   1.154 +    // statically known, array length and return that length
   1.155 +    // (via `*length`) if so. Otherwise returns false.
   1.156 +    bool hasKnownArrayLength(int32_t *length);
   1.157 +
   1.158 +    // Returns a `TypeDescrSet` representing the element
   1.159 +    // types of the various array types in this set. The returned set
   1.160 +    // may be the empty set.
   1.161 +    bool arrayElementType(IonBuilder &builder, TypeDescrSet *out);
   1.162 +
   1.163 +    //////////////////////////////////////////////////////////////////////
   1.164 +    // Struct operations
   1.165 +    //
   1.166 +    // Only valid when `kind() == TypeDescr::Struct`
   1.167 +
   1.168 +    // Searches the type in the set for a field named `id`. All
   1.169 +    // possible types must agree on the offset of the field within the
   1.170 +    // structure and the possible types of the field must be
   1.171 +    // compatible. If any pair of types disagree on the offset or have
   1.172 +    // incompatible types for the field, then `*out` will be set to
   1.173 +    // the empty set.
   1.174 +    //
   1.175 +    // Upon success, `out` will be set to the set of possible types of
   1.176 +    // the field and `offset` will be set to the field's offset within
   1.177 +    // the struct (measured in bytes).
   1.178 +    //
   1.179 +    // The parameter `*index` is special. If all types agree on the
   1.180 +    // index of the field, then `*index` is set to the field index.
   1.181 +    // Otherwise, it is set to SIZE_MAX. Note that two types may agree
   1.182 +    // on the type and offset of a field but disagree about its index,
   1.183 +    // e.g. the field `c` in `new StructType({a: uint8, b: uint8, c:
   1.184 +    // uint16})` and `new StructType({a: uint16, c: uint16})`.
   1.185 +    bool fieldNamed(IonBuilder &builder,
   1.186 +                    jsid id,
   1.187 +                    int32_t *offset,
   1.188 +                    TypeDescrSet *out,
   1.189 +                    size_t *index);
   1.190 +};
   1.191 +
   1.192 +struct TypeDescrSetHasher
   1.193 +{
   1.194 +    typedef TypeDescrSet Lookup;
   1.195 +    static HashNumber hash(TypeDescrSet key);
   1.196 +    static bool match(TypeDescrSet key1,
   1.197 +                      TypeDescrSet key2);
   1.198 +};
   1.199 +
   1.200 +typedef js::HashSet<TypeDescrSet,
   1.201 +                    TypeDescrSetHasher,
   1.202 +                    IonAllocPolicy> TypeDescrSetHash;
   1.203 +
   1.204 +} // namespace jit
   1.205 +} // namespace js
   1.206 +
   1.207 +#endif

mercurial