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/TypePolicy.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/TypePolicy.h')
-rw-r--r-- | js/src/jit/TypePolicy.h | 536 |
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 */ |