| Index: src/compiler/simplified-operator.h
|
| diff --git a/src/compiler/simplified-operator.h b/src/compiler/simplified-operator.h
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..6410f2f66daa218dff0a480c0a5444009310bd35
|
| --- /dev/null
|
| +++ b/src/compiler/simplified-operator.h
|
| @@ -0,0 +1,177 @@
|
| +// Copyright 2014 the V8 project authors. All rights reserved.
|
| +// Use of this source code is governed by a BSD-style license that can be
|
| +// found in the LICENSE file.
|
| +
|
| +#ifndef V8_COMPILER_SIMPLIFIED_OPERATOR_H_
|
| +#define V8_COMPILER_SIMPLIFIED_OPERATOR_H_
|
| +
|
| +#include "src/compiler/machine-operator.h"
|
| +#include "src/compiler/opcodes.h"
|
| +#include "src/zone.h"
|
| +
|
| +namespace v8 {
|
| +namespace internal {
|
| +namespace compiler {
|
| +
|
| +// An access descriptor for loads/stores from/to fixed structures
|
| +// like field accesses of heap objects.
|
| +struct FieldAccess {
|
| + int offset;
|
| + Handle<Name> name; // debug only.
|
| + Type* type;
|
| + MachineRepresentation representation;
|
| +};
|
| +
|
| +
|
| +// An access descriptor for loads/stores of indexed structures
|
| +// like characters in strings or off-heap backing stores.
|
| +struct ElementAccess {
|
| + int header_size;
|
| + Type* type;
|
| + MachineRepresentation representation;
|
| +};
|
| +
|
| +
|
| +// If the accessed object is not a heap object, add this to the header_size.
|
| +static const int kNonHeapObjectHeaderSize = kHeapObjectTag;
|
| +
|
| +
|
| +// Specialization for static parameters of type {FieldAccess}.
|
| +template <>
|
| +struct StaticParameterTraits<const FieldAccess> {
|
| + static OStream& PrintTo(OStream& os, const FieldAccess& val) { // NOLINT
|
| + return os << val.offset;
|
| + }
|
| + static int HashCode(const FieldAccess& val) {
|
| + return (val.offset < 16) | (val.representation & 0xffff);
|
| + }
|
| + static bool Equals(const FieldAccess& a, const FieldAccess& b) {
|
| + return a.offset == b.offset && a.representation == b.representation &&
|
| + a.type->Is(b.type);
|
| + }
|
| +};
|
| +
|
| +
|
| +// Specialization for static parameters of type {ElementAccess}.
|
| +template <>
|
| +struct StaticParameterTraits<const ElementAccess> {
|
| + static OStream& PrintTo(OStream& os, const ElementAccess& val) { // NOLINT
|
| + return os << val.header_size;
|
| + }
|
| + static int HashCode(const ElementAccess& val) {
|
| + return (val.header_size < 16) | (val.representation & 0xffff);
|
| + }
|
| + static bool Equals(const ElementAccess& a, const ElementAccess& b) {
|
| + return a.header_size == b.header_size &&
|
| + a.representation == b.representation && a.type->Is(b.type);
|
| + }
|
| +};
|
| +
|
| +
|
| +inline const FieldAccess FieldAccessOf(Operator* op) {
|
| + ASSERT(op->opcode() == IrOpcode::kLoadField ||
|
| + op->opcode() == IrOpcode::kStoreField);
|
| + return static_cast<Operator1<FieldAccess>*>(op)->parameter();
|
| +}
|
| +
|
| +
|
| +inline const ElementAccess ElementAccessOf(Operator* op) {
|
| + ASSERT(op->opcode() == IrOpcode::kLoadElement ||
|
| + op->opcode() == IrOpcode::kStoreElement);
|
| + return static_cast<Operator1<ElementAccess>*>(op)->parameter();
|
| +}
|
| +
|
| +
|
| +// Interface for building simplified operators, which represent the
|
| +// medium-level operations of V8, including adding numbers, allocating objects,
|
| +// indexing into objects and arrays, etc.
|
| +// All operators are typed but many are representation independent.
|
| +
|
| +// Number values from JS can be in one of these representations:
|
| +// - Tagged: word-sized integer that is either
|
| +// - a signed small integer (31 or 32 bits plus a tag)
|
| +// - a tagged pointer to a HeapNumber object that has a float64 field
|
| +// - Int32: an untagged signed 32-bit integer
|
| +// - Uint32: an untagged unsigned 32-bit integer
|
| +// - Float64: an untagged float64
|
| +
|
| +// Additional representations for intermediate code or non-JS code:
|
| +// - Int64: an untagged signed 64-bit integer
|
| +// - Uint64: an untagged unsigned 64-bit integer
|
| +// - Float32: an untagged float32
|
| +
|
| +// Boolean values can be:
|
| +// - Bool: a tagged pointer to either the canonical JS #false or
|
| +// the canonical JS #true object
|
| +// - Bit: an untagged integer 0 or 1, but word-sized
|
| +class SimplifiedOperatorBuilder {
|
| + public:
|
| + explicit inline SimplifiedOperatorBuilder(Zone* zone) : zone_(zone) {}
|
| +
|
| +#define SIMPLE(name, properties, inputs, outputs) \
|
| + return new (zone_) \
|
| + SimpleOperator(IrOpcode::k##name, properties, inputs, outputs, #name);
|
| +
|
| +#define OP1(name, ptype, pname, properties, inputs, outputs) \
|
| + return new (zone_) \
|
| + Operator1<ptype>(IrOpcode::k##name, properties | Operator::kNoThrow, \
|
| + inputs, outputs, #name, pname)
|
| +
|
| +#define UNOP(name) SIMPLE(name, Operator::kPure, 1, 1)
|
| +#define BINOP(name) SIMPLE(name, Operator::kPure, 2, 1)
|
| +
|
| + Operator* BooleanNot() const { UNOP(BooleanNot); }
|
| +
|
| + Operator* NumberEqual() const { BINOP(NumberEqual); }
|
| + Operator* NumberLessThan() const { BINOP(NumberLessThan); }
|
| + Operator* NumberLessThanOrEqual() const { BINOP(NumberLessThanOrEqual); }
|
| + Operator* NumberAdd() const { BINOP(NumberAdd); }
|
| + Operator* NumberSubtract() const { BINOP(NumberSubtract); }
|
| + Operator* NumberMultiply() const { BINOP(NumberMultiply); }
|
| + Operator* NumberDivide() const { BINOP(NumberDivide); }
|
| + Operator* NumberModulus() const { BINOP(NumberModulus); }
|
| + Operator* NumberToInt32() const { UNOP(NumberToInt32); }
|
| + Operator* NumberToUint32() const { UNOP(NumberToUint32); }
|
| +
|
| + Operator* ReferenceEqual(Type* type) const { BINOP(ReferenceEqual); }
|
| +
|
| + Operator* StringEqual() const { BINOP(StringEqual); }
|
| + Operator* StringLessThan() const { BINOP(StringLessThan); }
|
| + Operator* StringLessThanOrEqual() const { BINOP(StringLessThanOrEqual); }
|
| + Operator* StringAdd() const { BINOP(StringAdd); }
|
| +
|
| + Operator* ChangeTaggedToInt32() const { UNOP(ChangeTaggedToInt32); }
|
| + Operator* ChangeTaggedToUint32() const { UNOP(ChangeTaggedToUint32); }
|
| + Operator* ChangeTaggedToFloat64() const { UNOP(ChangeTaggedToFloat64); }
|
| + Operator* ChangeInt32ToTagged() const { UNOP(ChangeInt32ToTagged); }
|
| + Operator* ChangeUint32ToTagged() const { UNOP(ChangeUint32ToTagged); }
|
| + Operator* ChangeFloat64ToTagged() const { UNOP(ChangeFloat64ToTagged); }
|
| + Operator* ChangeBoolToBit() const { UNOP(ChangeBoolToBit); }
|
| + Operator* ChangeBitToBool() const { UNOP(ChangeBitToBool); }
|
| +
|
| + Operator* LoadField(const FieldAccess& access) const {
|
| + OP1(LoadField, FieldAccess, access, Operator::kNoWrite, 1, 1);
|
| + }
|
| + Operator* StoreField(const FieldAccess& access) const {
|
| + OP1(StoreField, FieldAccess, access, Operator::kNoRead, 2, 0);
|
| + }
|
| + Operator* LoadElement(const ElementAccess& access) const {
|
| + OP1(LoadElement, ElementAccess, access, Operator::kNoWrite, 2, 1);
|
| + }
|
| + Operator* StoreElement(const ElementAccess& access) const {
|
| + OP1(StoreElement, ElementAccess, access, Operator::kNoRead, 3, 0);
|
| + }
|
| +
|
| +#undef BINOP
|
| +#undef UNOP
|
| +#undef OP1
|
| +#undef SIMPLE
|
| +
|
| + private:
|
| + Zone* zone_;
|
| +};
|
| +}
|
| +}
|
| +} // namespace v8::internal::compiler
|
| +
|
| +#endif // V8_COMPILER_SIMPLIFIED_OPERATOR_H_
|
|
|