diff options
author | Matt A. Tobin <mattatobin@localhost.localdomain> | 2018-02-02 04:16:08 -0500 |
---|---|---|
committer | Matt A. Tobin <mattatobin@localhost.localdomain> | 2018-02-02 04:16:08 -0500 |
commit | 5f8de423f190bbb79a62f804151bc24824fa32d8 (patch) | |
tree | 10027f336435511475e392454359edea8e25895d /js/src/jit/TypedObjectPrediction.h | |
parent | 49ee0794b5d912db1f95dce6eb52d781dc210db5 (diff) | |
download | UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar.gz UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar.lz UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar.xz UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.zip |
Add m-esr52 at 52.6.0
Diffstat (limited to 'js/src/jit/TypedObjectPrediction.h')
-rw-r--r-- | js/src/jit/TypedObjectPrediction.h | 201 |
1 files changed, 201 insertions, 0 deletions
diff --git a/js/src/jit/TypedObjectPrediction.h b/js/src/jit/TypedObjectPrediction.h new file mode 100644 index 000000000..2e3caf2cf --- /dev/null +++ b/js/src/jit/TypedObjectPrediction.h @@ -0,0 +1,201 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * vim: set ts=8 sts=4 et sw=4 tw=99: + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef jit_TypedObjectPrediction_h +#define jit_TypedObjectPrediction_h + +#include "builtin/TypedObject.h" +#include "jit/JitAllocPolicy.h" + +namespace js { +namespace jit { + +// A TypedObjectPrediction summarizes what we know about the type of a +// typed object at a given point (if anything). The prediction will +// begin as precise as possible and degrade to less precise as more +// typed object types are merged using |addDescr()|. +// +// To create a TypedObjectPrediction from TI, one initially creates an +// empty prediction using the |TypedObjectPrediction()| constructor, +// and then invokes |addDescr()| with the prototype of each typed +// object. The prediction will automatically downgrade to less and +// less specific settings as needed. Note that creating a prediction +// in this way can never yield precise array dimensions, since TI only +// tracks the prototype. +// +// TypedObjectPredictions can also result from other predictions using +// the query methods (e.g., |arrayElementType()|). In those cases, the +// precise array dimensions may be known. +// +// To query a prediction, you must first check whether it is "useless" +// using |isUseless()|. If this is true, there is no usable +// information to be extracted. Otherwise, you can inquire after the +// |kind()| of the data (struct, array, etc) and from there make more +// specific queries. +class TypedObjectPrediction { + public: + enum PredictionKind { + // No data. + Empty, + + // Inconsistent data. + Inconsistent, + + // Multiple different struct types flow into the same location, + // but they share fields in common. Prefix indicates that the first + // N fields of some struct type are known to be valid. This occurs + // in a subtyping scenario. + Prefix, + + // The TypeDescr of the value is known. This is the most specific + // possible value and includes precise array bounds. + Descr + }; + + struct PrefixData { + const StructTypeDescr* descr; + size_t fields; + }; + + union Data { + const TypeDescr* descr; + PrefixData prefix; + }; + + private: + PredictionKind kind_; + Data data_; + + PredictionKind predictionKind() const { + return kind_; + } + + void markInconsistent() { + kind_ = Inconsistent; + } + + const TypeDescr& descr() const { + MOZ_ASSERT(predictionKind() == Descr); + return *data_.descr; + } + + const PrefixData& prefix() const { + MOZ_ASSERT(predictionKind() == Prefix); + return data_.prefix; + } + + void setDescr(const TypeDescr& descr) { + kind_ = Descr; + data_.descr = &descr; + } + + void setPrefix(const StructTypeDescr& descr, size_t fields) { + kind_ = Prefix; + data_.prefix.descr = &descr; + data_.prefix.fields = fields; + } + + void markAsCommonPrefix(const StructTypeDescr& descrA, + const StructTypeDescr& descrB, + size_t max); + + template<typename T> + typename T::Type extractType() const; + + bool hasFieldNamedPrefix(const StructTypeDescr& descr, + size_t fieldCount, + jsid id, + size_t* fieldOffset, + TypedObjectPrediction* out, + size_t* index) const; + + public: + + /////////////////////////////////////////////////////////////////////////// + // Constructing a prediction. Generally, you start with an empty + // prediction and invoke addDescr() repeatedly. + + TypedObjectPrediction() { + kind_ = Empty; + } + + explicit TypedObjectPrediction(const TypeDescr& descr) { + setDescr(descr); + } + + TypedObjectPrediction(const StructTypeDescr& descr, size_t fields) { + setPrefix(descr, fields); + } + + void addDescr(const TypeDescr& descr); + + /////////////////////////////////////////////////////////////////////////// + // Queries that are always valid. + + bool isUseless() const { + return predictionKind() == Empty || predictionKind() == Inconsistent; + } + + // Determines whether we can predict the prototype for the typed + // object instance. Returns null if we cannot or if the typed + // object is of scalar/reference kind, in which case instances are + // not objects and hence do not have a (publicly available) + // prototype. + const TypedProto* getKnownPrototype() const; + + /////////////////////////////////////////////////////////////////////////// + // Queries that are valid if not useless. + + type::Kind kind() const; + + bool ofArrayKind() const; + + // Returns true if the size of this typed object is statically + // known and sets |*out| to that size. Otherwise returns false. + // + // The size may not be statically known if (1) the object is + // an array whose dimensions are unknown or (2) only a prefix + // of its type is known. + bool hasKnownSize(uint32_t* out) const; + + ////////////////////////////////////////////////////////////////////// + // Simple operations + // + // Only valid when |kind()| is Scalar, Reference, or Simd (as appropriate). + + ScalarTypeDescr::Type scalarType() const; + ReferenceTypeDescr::Type referenceType() const; + SimdType simdType() const; + + /////////////////////////////////////////////////////////////////////////// + // Queries valid only for arrays. + + // Returns true if the length of the array is statically known, + // and sets |*length| appropriately. Otherwise returns false. + bool hasKnownArrayLength(int32_t* length) const; + + // Returns a prediction for the array element type, if any. + TypedObjectPrediction arrayElementType() const; + + ////////////////////////////////////////////////////////////////////// + // Struct operations + // + // Only valid when |kind() == TypeDescr::Struct| + + // Returns true if the predicted type includes a field named |id| + // and sets |*fieldOffset|, |*fieldType|, and |*fieldIndex| with + // the offset (in bytes), type, and index of the field + // respectively. Otherwise returns false. + bool hasFieldNamed(jsid id, + size_t* fieldOffset, + TypedObjectPrediction* fieldType, + size_t* fieldIndex) const; +}; + +} // namespace jit +} // namespace js + +#endif |