summaryrefslogtreecommitdiffstats
path: root/js/src/jit/TypedObjectPrediction.h
diff options
context:
space:
mode:
authorMatt A. Tobin <mattatobin@localhost.localdomain>2018-02-02 04:16:08 -0500
committerMatt A. Tobin <mattatobin@localhost.localdomain>2018-02-02 04:16:08 -0500
commit5f8de423f190bbb79a62f804151bc24824fa32d8 (patch)
tree10027f336435511475e392454359edea8e25895d /js/src/jit/TypedObjectPrediction.h
parent49ee0794b5d912db1f95dce6eb52d781dc210db5 (diff)
downloadUXP-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.h201
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