summaryrefslogtreecommitdiffstats
path: root/js/src/jit/TypePolicy.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/TypePolicy.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/TypePolicy.h')
-rw-r--r--js/src/jit/TypePolicy.h536
1 files changed, 536 insertions, 0 deletions
diff --git a/js/src/jit/TypePolicy.h b/js/src/jit/TypePolicy.h
new file mode 100644
index 000000000..1c7160220
--- /dev/null
+++ b/js/src/jit/TypePolicy.h
@@ -0,0 +1,536 @@
+/* -*- 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_TypePolicy_h
+#define jit_TypePolicy_h
+
+#include "jit/IonTypes.h"
+#include "jit/JitAllocPolicy.h"
+
+namespace js {
+namespace jit {
+
+class MInstruction;
+class MDefinition;
+
+extern MDefinition*
+AlwaysBoxAt(TempAllocator& alloc, MInstruction* at, MDefinition* operand);
+
+// A type policy directs the type analysis phases, which insert conversion,
+// boxing, unboxing, and type changes as necessary.
+class TypePolicy
+{
+ public:
+ // Analyze the inputs of the instruction and perform one of the following
+ // actions for each input:
+ // * Nothing; the input already type-checks.
+ // * If untyped, optionally ask the input to try and specialize its value.
+ // * Replace the operand with a conversion instruction.
+ // * Insert an unconditional deoptimization (no conversion possible).
+ virtual MOZ_MUST_USE bool adjustInputs(TempAllocator& alloc, MInstruction* def) = 0;
+};
+
+struct TypeSpecializationData
+{
+ protected:
+ // Specifies three levels of specialization:
+ // - < Value. This input is expected and required.
+ // - == None. This op should not be specialized.
+ MIRType specialization_;
+
+ MIRType thisTypeSpecialization() {
+ return specialization_;
+ }
+
+ public:
+ MIRType specialization() const {
+ return specialization_;
+ }
+};
+
+#define EMPTY_DATA_ \
+ struct Data \
+ { \
+ static TypePolicy* thisTypePolicy(); \
+ }
+
+#define INHERIT_DATA_(DATA_TYPE) \
+ struct Data : public DATA_TYPE \
+ { \
+ static TypePolicy* thisTypePolicy(); \
+ }
+
+#define SPECIALIZATION_DATA_ INHERIT_DATA_(TypeSpecializationData)
+
+class NoTypePolicy
+{
+ public:
+ struct Data
+ {
+ static TypePolicy* thisTypePolicy() {
+ return nullptr;
+ }
+ };
+};
+
+class BoxInputsPolicy final : public TypePolicy
+{
+ public:
+ SPECIALIZATION_DATA_;
+ static MOZ_MUST_USE bool staticAdjustInputs(TempAllocator& alloc, MInstruction* def);
+ virtual MOZ_MUST_USE bool adjustInputs(TempAllocator& alloc, MInstruction* def) override {
+ return staticAdjustInputs(alloc, def);
+ }
+};
+
+class ArithPolicy final : public TypePolicy
+{
+ public:
+ SPECIALIZATION_DATA_;
+ virtual MOZ_MUST_USE bool adjustInputs(TempAllocator& alloc, MInstruction* def) override;
+};
+
+class AllDoublePolicy final : public TypePolicy
+{
+ public:
+ EMPTY_DATA_;
+ MOZ_MUST_USE bool adjustInputs(TempAllocator& alloc, MInstruction* def);
+};
+
+class BitwisePolicy final : public TypePolicy
+{
+ public:
+ SPECIALIZATION_DATA_;
+ virtual MOZ_MUST_USE bool adjustInputs(TempAllocator& alloc, MInstruction* def) override;
+};
+
+class ComparePolicy final : public TypePolicy
+{
+ public:
+ EMPTY_DATA_;
+ virtual MOZ_MUST_USE bool adjustInputs(TempAllocator& alloc, MInstruction* def) override;
+};
+
+// Policy for MTest instructions.
+class TestPolicy final : public TypePolicy
+{
+ public:
+ EMPTY_DATA_;
+ virtual MOZ_MUST_USE bool adjustInputs(TempAllocator& alloc, MInstruction* ins) override;
+};
+
+class TypeBarrierPolicy final : public TypePolicy
+{
+ public:
+ EMPTY_DATA_;
+ virtual MOZ_MUST_USE bool adjustInputs(TempAllocator& alloc, MInstruction* ins) override;
+};
+
+class CallPolicy final : public TypePolicy
+{
+ public:
+ EMPTY_DATA_;
+ virtual MOZ_MUST_USE bool adjustInputs(TempAllocator& alloc, MInstruction* def) override;
+};
+
+// Policy for MPow. First operand Double; second Double or Int32.
+class PowPolicy final : public TypePolicy
+{
+ public:
+ SPECIALIZATION_DATA_;
+ virtual MOZ_MUST_USE bool adjustInputs(TempAllocator& alloc, MInstruction* ins) override;
+};
+
+// Expect a string for operand Op. If the input is a Value, it is unboxed.
+template <unsigned Op>
+class StringPolicy final : public TypePolicy
+{
+ public:
+ EMPTY_DATA_;
+ static MOZ_MUST_USE bool staticAdjustInputs(TempAllocator& alloc, MInstruction* def);
+ virtual MOZ_MUST_USE bool adjustInputs(TempAllocator& alloc, MInstruction* def) override {
+ return staticAdjustInputs(alloc, def);
+ }
+};
+
+// Expect a string for operand Op. Else a ToString instruction is inserted.
+template <unsigned Op>
+class ConvertToStringPolicy final : public TypePolicy
+{
+ public:
+ EMPTY_DATA_;
+ static MOZ_MUST_USE bool staticAdjustInputs(TempAllocator& alloc, MInstruction* def);
+ virtual MOZ_MUST_USE bool adjustInputs(TempAllocator& alloc, MInstruction* def) override {
+ return staticAdjustInputs(alloc, def);
+ }
+};
+
+// Expect an Boolean for operand Op. If the input is a Value, it is unboxed.
+template <unsigned Op>
+class BooleanPolicy final : private TypePolicy
+{
+ public:
+ EMPTY_DATA_;
+ static MOZ_MUST_USE bool staticAdjustInputs(TempAllocator& alloc, MInstruction* def);
+ virtual MOZ_MUST_USE bool adjustInputs(TempAllocator& alloc, MInstruction* def) override {
+ return staticAdjustInputs(alloc, def);
+ }
+};
+
+// Expect an Int for operand Op. If the input is a Value, it is unboxed.
+template <unsigned Op>
+class IntPolicy final : private TypePolicy
+{
+ public:
+ EMPTY_DATA_;
+ static MOZ_MUST_USE bool staticAdjustInputs(TempAllocator& alloc, MInstruction* def);
+ virtual MOZ_MUST_USE bool adjustInputs(TempAllocator& alloc, MInstruction* def) override {
+ return staticAdjustInputs(alloc, def);
+ }
+};
+
+// Expect an Int for operand Op. Else a ToInt32 instruction is inserted.
+template <unsigned Op>
+class ConvertToInt32Policy final : public TypePolicy
+{
+ public:
+ EMPTY_DATA_;
+ static MOZ_MUST_USE bool staticAdjustInputs(TempAllocator& alloc, MInstruction* def);
+ virtual MOZ_MUST_USE bool adjustInputs(TempAllocator& alloc, MInstruction* def) override {
+ return staticAdjustInputs(alloc, def);
+ }
+};
+
+// Expect an Int for operand Op. Else a TruncateToInt32 instruction is inserted.
+template <unsigned Op>
+class TruncateToInt32Policy final : public TypePolicy
+{
+ public:
+ EMPTY_DATA_;
+ static MOZ_MUST_USE bool staticAdjustInputs(TempAllocator& alloc, MInstruction* def);
+ virtual MOZ_MUST_USE bool adjustInputs(TempAllocator& alloc, MInstruction* def) override {
+ return staticAdjustInputs(alloc, def);
+ }
+};
+
+// Expect a double for operand Op. If the input is a Value, it is unboxed.
+template <unsigned Op>
+class DoublePolicy final : public TypePolicy
+{
+ public:
+ EMPTY_DATA_;
+ static MOZ_MUST_USE bool staticAdjustInputs(TempAllocator& alloc, MInstruction* def);
+ virtual MOZ_MUST_USE bool adjustInputs(TempAllocator& alloc, MInstruction* def) override {
+ return staticAdjustInputs(alloc, def);
+ }
+};
+
+// Expect a float32 for operand Op. If the input is a Value, it is unboxed.
+template <unsigned Op>
+class Float32Policy final : public TypePolicy
+{
+ public:
+ EMPTY_DATA_;
+ static MOZ_MUST_USE bool staticAdjustInputs(TempAllocator& alloc, MInstruction* def);
+ virtual MOZ_MUST_USE bool adjustInputs(TempAllocator& alloc, MInstruction* def) override {
+ return staticAdjustInputs(alloc, def);
+ }
+};
+
+// Expect a float32 OR a double for operand Op, but will prioritize Float32
+// if the result type is set as such. If the input is a Value, it is unboxed.
+template <unsigned Op>
+class FloatingPointPolicy final : public TypePolicy
+{
+ public:
+ SPECIALIZATION_DATA_;
+ virtual MOZ_MUST_USE bool adjustInputs(TempAllocator& alloc, MInstruction* def) override;
+};
+
+template <unsigned Op>
+class NoFloatPolicy final : public TypePolicy
+{
+ public:
+ EMPTY_DATA_;
+ static MOZ_MUST_USE bool staticAdjustInputs(TempAllocator& alloc, MInstruction* def);
+ virtual MOZ_MUST_USE bool adjustInputs(TempAllocator& alloc, MInstruction* def) override {
+ return staticAdjustInputs(alloc, def);
+ }
+};
+
+// Policy for guarding variadic instructions such as object / array state
+// instructions.
+template <unsigned FirstOp>
+class NoFloatPolicyAfter final : public TypePolicy
+{
+ public:
+ EMPTY_DATA_;
+ virtual MOZ_MUST_USE bool adjustInputs(TempAllocator& alloc, MInstruction* ins) override;
+};
+
+// Box objects or strings as an input to a ToDouble instruction.
+class ToDoublePolicy final : public TypePolicy
+{
+ public:
+ EMPTY_DATA_;
+ static MOZ_MUST_USE bool staticAdjustInputs(TempAllocator& alloc, MInstruction* def);
+ virtual MOZ_MUST_USE bool adjustInputs(TempAllocator& alloc, MInstruction* def) override {
+ return staticAdjustInputs(alloc, def);
+ }
+};
+
+// Box objects, strings and undefined as input to a ToInt32 instruction.
+class ToInt32Policy final : public TypePolicy
+{
+ public:
+ EMPTY_DATA_;
+ static MOZ_MUST_USE bool staticAdjustInputs(TempAllocator& alloc, MInstruction* def);
+ virtual MOZ_MUST_USE bool adjustInputs(TempAllocator& alloc, MInstruction* def) override {
+ return staticAdjustInputs(alloc, def);
+ }
+};
+
+// Box objects as input to a ToString instruction.
+class ToStringPolicy final : public TypePolicy
+{
+ public:
+ EMPTY_DATA_;
+ static MOZ_MUST_USE bool staticAdjustInputs(TempAllocator& alloc, MInstruction* def);
+ virtual MOZ_MUST_USE bool adjustInputs(TempAllocator& alloc, MInstruction* def) override {
+ return staticAdjustInputs(alloc, def);
+ }
+};
+
+template <unsigned Op>
+class ObjectPolicy final : public TypePolicy
+{
+ public:
+ EMPTY_DATA_;
+ static MOZ_MUST_USE bool staticAdjustInputs(TempAllocator& alloc, MInstruction* ins);
+ virtual MOZ_MUST_USE bool adjustInputs(TempAllocator& alloc, MInstruction* ins) override {
+ return staticAdjustInputs(alloc, ins);
+ }
+};
+
+// Single-object input. If the input is a Value, it is unboxed. If it is
+// a primitive, we use ValueToNonNullObject.
+typedef ObjectPolicy<0> SingleObjectPolicy;
+
+// Convert an operand to have a type identical to the scalar type of the
+// returned type of the instruction.
+template <unsigned Op>
+class SimdScalarPolicy final : public TypePolicy
+{
+ public:
+ EMPTY_DATA_;
+ static MOZ_MUST_USE bool staticAdjustInputs(TempAllocator& alloc, MInstruction* def);
+ virtual MOZ_MUST_USE bool adjustInputs(TempAllocator& alloc, MInstruction* def) override {
+ return staticAdjustInputs(alloc, def);
+ }
+};
+
+class SimdAllPolicy final : public TypePolicy
+{
+ public:
+ SPECIALIZATION_DATA_;
+ virtual MOZ_MUST_USE bool adjustInputs(TempAllocator& alloc, MInstruction* ins) override;
+};
+
+template <unsigned Op>
+class SimdPolicy final : public TypePolicy
+{
+ public:
+ SPECIALIZATION_DATA_;
+ virtual MOZ_MUST_USE bool adjustInputs(TempAllocator& alloc, MInstruction* ins) override;
+};
+
+class SimdSelectPolicy final : public TypePolicy
+{
+ public:
+ SPECIALIZATION_DATA_;
+ virtual MOZ_MUST_USE bool adjustInputs(TempAllocator& alloc, MInstruction* ins) override;
+};
+
+class SimdShufflePolicy final : public TypePolicy
+{
+ public:
+ SPECIALIZATION_DATA_;
+ virtual MOZ_MUST_USE bool adjustInputs(TempAllocator& alloc, MInstruction* ins) override;
+};
+
+// SIMD value-type policy, use the returned type of the instruction to determine
+// how to unbox its operand.
+template <unsigned Op>
+class SimdSameAsReturnedTypePolicy final : public TypePolicy
+{
+ public:
+ EMPTY_DATA_;
+ static MOZ_MUST_USE bool staticAdjustInputs(TempAllocator& alloc, MInstruction* ins);
+ virtual MOZ_MUST_USE bool adjustInputs(TempAllocator& alloc, MInstruction* ins) override {
+ return staticAdjustInputs(alloc, ins);
+ }
+};
+
+template <unsigned Op>
+class BoxPolicy final : public TypePolicy
+{
+ public:
+ EMPTY_DATA_;
+ static MOZ_MUST_USE bool staticAdjustInputs(TempAllocator& alloc, MInstruction* ins);
+ virtual MOZ_MUST_USE bool adjustInputs(TempAllocator& alloc, MInstruction* ins) override {
+ return staticAdjustInputs(alloc, ins);
+ }
+};
+
+// Boxes everything except inputs of type Type.
+template <unsigned Op, MIRType Type>
+class BoxExceptPolicy final : public TypePolicy
+{
+ public:
+ EMPTY_DATA_;
+ static MOZ_MUST_USE bool staticAdjustInputs(TempAllocator& alloc, MInstruction* ins);
+ MOZ_MUST_USE bool adjustInputs(TempAllocator& alloc, MInstruction* ins) {
+ return staticAdjustInputs(alloc, ins);
+ }
+};
+
+// Box if not a typical property id (string, symbol, int32).
+template <unsigned Op>
+class CacheIdPolicy final : public TypePolicy
+{
+ public:
+ EMPTY_DATA_;
+ static MOZ_MUST_USE bool staticAdjustInputs(TempAllocator& alloc, MInstruction* ins);
+ MOZ_MUST_USE bool adjustInputs(TempAllocator& alloc, MInstruction* ins) {
+ return staticAdjustInputs(alloc, ins);
+ }
+};
+
+// Combine multiple policies.
+template <class Lhs, class Rhs>
+class MixPolicy final : public TypePolicy
+{
+ public:
+ EMPTY_DATA_;
+ static MOZ_MUST_USE bool staticAdjustInputs(TempAllocator& alloc, MInstruction* ins) {
+ return Lhs::staticAdjustInputs(alloc, ins) && Rhs::staticAdjustInputs(alloc, ins);
+ }
+ virtual MOZ_MUST_USE bool adjustInputs(TempAllocator& alloc, MInstruction* ins) override {
+ return staticAdjustInputs(alloc, ins);
+ }
+};
+
+// Combine three policies.
+template <class Policy1, class Policy2, class Policy3>
+class Mix3Policy final : public TypePolicy
+{
+ public:
+ EMPTY_DATA_;
+ static MOZ_MUST_USE bool staticAdjustInputs(TempAllocator& alloc, MInstruction* ins) {
+ return Policy1::staticAdjustInputs(alloc, ins) &&
+ Policy2::staticAdjustInputs(alloc, ins) &&
+ Policy3::staticAdjustInputs(alloc, ins);
+ }
+ virtual MOZ_MUST_USE bool adjustInputs(TempAllocator& alloc, MInstruction* ins) override {
+ return staticAdjustInputs(alloc, ins);
+ }
+};
+
+// Combine four policies. (Missing variadic templates yet?)
+template <class Policy1, class Policy2, class Policy3, class Policy4>
+class Mix4Policy : public TypePolicy
+{
+ public:
+ EMPTY_DATA_;
+ static MOZ_MUST_USE bool staticAdjustInputs(TempAllocator& alloc, MInstruction* ins) {
+ return Policy1::staticAdjustInputs(alloc, ins) &&
+ Policy2::staticAdjustInputs(alloc, ins) &&
+ Policy3::staticAdjustInputs(alloc, ins) &&
+ Policy4::staticAdjustInputs(alloc, ins);
+ }
+ virtual MOZ_MUST_USE bool adjustInputs(TempAllocator& alloc, MInstruction* ins) override {
+ return staticAdjustInputs(alloc, ins);
+ }
+};
+
+class CallSetElementPolicy final : public TypePolicy
+{
+ public:
+ EMPTY_DATA_;
+ virtual MOZ_MUST_USE bool adjustInputs(TempAllocator& alloc, MInstruction* def) override;
+};
+
+// First operand will be boxed to a Value (except for an object)
+// Second operand (if specified) will forcefully be unboxed to an object
+class InstanceOfPolicy final : public TypePolicy
+{
+ public:
+ EMPTY_DATA_;
+ virtual MOZ_MUST_USE bool adjustInputs(TempAllocator& alloc, MInstruction* def) override;
+};
+
+class StoreTypedArrayHolePolicy;
+class StoreTypedArrayElementStaticPolicy;
+
+class StoreUnboxedScalarPolicy : public TypePolicy
+{
+ private:
+ static MOZ_MUST_USE bool adjustValueInput(TempAllocator& alloc, MInstruction* ins,
+ Scalar::Type arrayType, MDefinition* value,
+ int valueOperand);
+
+ friend class StoreTypedArrayHolePolicy;
+ friend class StoreTypedArrayElementStaticPolicy;
+
+ public:
+ EMPTY_DATA_;
+ virtual MOZ_MUST_USE bool adjustInputs(TempAllocator& alloc, MInstruction* ins) override;
+};
+
+class StoreTypedArrayHolePolicy final : public StoreUnboxedScalarPolicy
+{
+ public:
+ EMPTY_DATA_;
+ virtual MOZ_MUST_USE bool adjustInputs(TempAllocator& alloc, MInstruction* ins) override;
+};
+
+class StoreTypedArrayElementStaticPolicy final : public StoreUnboxedScalarPolicy
+{
+ public:
+ EMPTY_DATA_;
+ virtual MOZ_MUST_USE bool adjustInputs(TempAllocator& alloc, MInstruction* ins) override;
+};
+
+class StoreUnboxedObjectOrNullPolicy final : public TypePolicy
+{
+ public:
+ EMPTY_DATA_;
+ virtual MOZ_MUST_USE bool adjustInputs(TempAllocator& alloc, MInstruction* def) override;
+};
+
+// Accepts integers and doubles. Everything else is boxed.
+class ClampPolicy final : public TypePolicy
+{
+ public:
+ EMPTY_DATA_;
+ virtual MOZ_MUST_USE bool adjustInputs(TempAllocator& alloc, MInstruction* ins) override;
+};
+
+class FilterTypeSetPolicy final : public TypePolicy
+{
+ public:
+ EMPTY_DATA_;
+ virtual MOZ_MUST_USE bool adjustInputs(TempAllocator& alloc, MInstruction* ins) override;
+};
+
+#undef SPECIALIZATION_DATA_
+#undef INHERIT_DATA_
+#undef EMPTY_DATA_
+
+} // namespace jit
+} // namespace js
+
+#endif /* jit_TypePolicy_h */