LCOV - code coverage report
Current view: top level - js/src/jit - TypedObjectPrediction.h (source / functions) Hit Total Coverage
Test: output.info Lines: 7 28 25.0 %
Date: 2017-07-14 16:53:18 Functions: 3 9 33.3 %
Legend: Lines: hit not hit

          Line data    Source code
       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/. */
       6             : 
       7             : #ifndef jit_TypedObjectPrediction_h
       8             : #define jit_TypedObjectPrediction_h
       9             : 
      10             : #include "builtin/TypedObject.h"
      11             : #include "jit/JitAllocPolicy.h"
      12             : 
      13             : namespace js {
      14             : namespace jit {
      15             : 
      16             : // A TypedObjectPrediction summarizes what we know about the type of a
      17             : // typed object at a given point (if anything). The prediction will
      18             : // begin as precise as possible and degrade to less precise as more
      19             : // typed object types are merged using |addDescr()|.
      20             : //
      21             : // To create a TypedObjectPrediction from TI, one initially creates an
      22             : // empty prediction using the |TypedObjectPrediction()| constructor,
      23             : // and then invokes |addDescr()| with the prototype of each typed
      24             : // object. The prediction will automatically downgrade to less and
      25             : // less specific settings as needed. Note that creating a prediction
      26             : // in this way can never yield precise array dimensions, since TI only
      27             : // tracks the prototype.
      28             : //
      29             : // TypedObjectPredictions can also result from other predictions using
      30             : // the query methods (e.g., |arrayElementType()|). In those cases, the
      31             : // precise array dimensions may be known.
      32             : //
      33             : // To query a prediction, you must first check whether it is "useless"
      34             : // using |isUseless()|. If this is true, there is no usable
      35             : // information to be extracted. Otherwise, you can inquire after the
      36             : // |kind()| of the data (struct, array, etc) and from there make more
      37             : // specific queries.
      38             : class TypedObjectPrediction {
      39             :   public:
      40             :     enum PredictionKind {
      41             :         // No data.
      42             :         Empty,
      43             : 
      44             :         // Inconsistent data.
      45             :         Inconsistent,
      46             : 
      47             :         // Multiple different struct types flow into the same location,
      48             :         // but they share fields in common. Prefix indicates that the first
      49             :         // N fields of some struct type are known to be valid. This occurs
      50             :         // in a subtyping scenario.
      51             :         Prefix,
      52             : 
      53             :         // The TypeDescr of the value is known. This is the most specific
      54             :         // possible value and includes precise array bounds.
      55             :         Descr
      56             :     };
      57             : 
      58             :     struct PrefixData {
      59             :         const StructTypeDescr* descr;
      60             :         size_t fields;
      61             :     };
      62             : 
      63             :     union Data {
      64             :         const TypeDescr* descr;
      65             :         PrefixData prefix;
      66             :     };
      67             : 
      68             :   private:
      69             :     PredictionKind kind_;
      70             :     Data data_;
      71             : 
      72         104 :     PredictionKind predictionKind() const {
      73         104 :         return kind_;
      74             :     }
      75             : 
      76           0 :     void markInconsistent() {
      77           0 :         kind_ = Inconsistent;
      78           0 :     }
      79             : 
      80           0 :     const TypeDescr& descr() const {
      81           0 :         MOZ_ASSERT(predictionKind() == Descr);
      82           0 :         return *data_.descr;
      83             :     }
      84             : 
      85           0 :     const PrefixData& prefix() const {
      86           0 :         MOZ_ASSERT(predictionKind() == Prefix);
      87           0 :         return data_.prefix;
      88             :     }
      89             : 
      90           0 :     void setDescr(const TypeDescr& descr) {
      91           0 :         kind_ = Descr;
      92           0 :         data_.descr = &descr;
      93           0 :     }
      94             : 
      95           0 :     void setPrefix(const StructTypeDescr& descr, size_t fields) {
      96           0 :         kind_ = Prefix;
      97           0 :         data_.prefix.descr = &descr;
      98           0 :         data_.prefix.fields = fields;
      99           0 :     }
     100             : 
     101             :     void markAsCommonPrefix(const StructTypeDescr& descrA,
     102             :                             const StructTypeDescr& descrB,
     103             :                             size_t max);
     104             : 
     105             :     template<typename T>
     106             :     typename T::Type extractType() const;
     107             : 
     108             :     bool hasFieldNamedPrefix(const StructTypeDescr& descr,
     109             :                              size_t fieldCount,
     110             :                              jsid id,
     111             :                              size_t* fieldOffset,
     112             :                              TypedObjectPrediction* out,
     113             :                              size_t* index) const;
     114             : 
     115             :   public:
     116             : 
     117             :     ///////////////////////////////////////////////////////////////////////////
     118             :     // Constructing a prediction. Generally, you start with an empty
     119             :     // prediction and invoke addDescr() repeatedly.
     120             : 
     121         250 :     TypedObjectPrediction() {
     122         250 :         kind_ = Empty;
     123         250 :     }
     124             : 
     125           0 :     explicit TypedObjectPrediction(const TypeDescr& descr) {
     126           0 :         setDescr(descr);
     127           0 :     }
     128             : 
     129             :     TypedObjectPrediction(const StructTypeDescr& descr, size_t fields) {
     130             :         setPrefix(descr, fields);
     131             :     }
     132             : 
     133             :     void addDescr(const TypeDescr& descr);
     134             : 
     135             :     ///////////////////////////////////////////////////////////////////////////
     136             :     // Queries that are always valid.
     137             : 
     138         104 :     bool isUseless() const {
     139         104 :         return predictionKind() == Empty || predictionKind() == Inconsistent;
     140             :     }
     141             : 
     142             :     // Determines whether we can predict the prototype for the typed
     143             :     // object instance. Returns null if we cannot or if the typed
     144             :     // object is of scalar/reference kind, in which case instances are
     145             :     // not objects and hence do not have a (publicly available)
     146             :     // prototype.
     147             :     const TypedProto* getKnownPrototype() const;
     148             : 
     149             :     ///////////////////////////////////////////////////////////////////////////
     150             :     // Queries that are valid if not useless.
     151             : 
     152             :     type::Kind kind() const;
     153             : 
     154             :     bool ofArrayKind() const;
     155             : 
     156             :     // Returns true if the size of this typed object is statically
     157             :     // known and sets |*out| to that size. Otherwise returns false.
     158             :     //
     159             :     // The size may not be statically known if (1) the object is
     160             :     // an array whose dimensions are unknown or (2) only a prefix
     161             :     // of its type is known.
     162             :     bool hasKnownSize(uint32_t* out) const;
     163             : 
     164             :     //////////////////////////////////////////////////////////////////////
     165             :     // Simple operations
     166             :     //
     167             :     // Only valid when |kind()| is Scalar, Reference, or Simd (as appropriate).
     168             : 
     169             :     ScalarTypeDescr::Type scalarType() const;
     170             :     ReferenceTypeDescr::Type referenceType() const;
     171             :     SimdType simdType() const;
     172             : 
     173             :     ///////////////////////////////////////////////////////////////////////////
     174             :     // Queries valid only for arrays.
     175             : 
     176             :     // Returns true if the length of the array is statically known,
     177             :     // and sets |*length| appropriately. Otherwise returns false.
     178             :     bool hasKnownArrayLength(int32_t* length) const;
     179             : 
     180             :     // Returns a prediction for the array element type, if any.
     181             :     TypedObjectPrediction arrayElementType() const;
     182             : 
     183             :     //////////////////////////////////////////////////////////////////////
     184             :     // Struct operations
     185             :     //
     186             :     // Only valid when |kind() == TypeDescr::Struct|
     187             : 
     188             :     // Returns true if the predicted type includes a field named |id|
     189             :     // and sets |*fieldOffset|, |*fieldType|, and |*fieldIndex| with
     190             :     // the offset (in bytes), type, and index of the field
     191             :     // respectively.  Otherwise returns false.
     192             :     bool hasFieldNamed(jsid id,
     193             :                        size_t* fieldOffset,
     194             :                        TypedObjectPrediction* fieldType,
     195             :                        size_t* fieldIndex) const;
     196             : };
     197             : 
     198             : } // namespace jit
     199             : } // namespace js
     200             : 
     201             : #endif

Generated by: LCOV version 1.13