Commit a17289f4 authored by bmeurer@chromium.org's avatar bmeurer@chromium.org

[turbofan] Drop broken StaticParameterTraits.

The StaticParameterTraits are broken by design, and cause way too much
trouble. The compilers usually pick the wrong specialization (i.e. the
default specialization is picked for Load and Phi even tho there is a
specialization for MachineType), which is not only the reason why GVN is
ineffective and slow, but can also lead to correctness issues in some
rare cases.

Also clean up some minor bugs/inconsistencies on the way.

TEST=cctest,unittests
R=svenpanne@chromium.org

Review URL: https://codereview.chromium.org/636893002

git-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@24437 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 304d91d2
......@@ -37,6 +37,7 @@
#include <cmath>
#include "src/api.h"
#include "src/base/cpu.h"
#include "src/base/functional.h"
#include "src/base/lazy-instance.h"
#include "src/base/platform/platform.h"
#include "src/builtins.h"
......@@ -1521,6 +1522,29 @@ ExternalReference ExternalReference::debug_step_in_fp_address(
}
bool operator==(ExternalReference lhs, ExternalReference rhs) {
return lhs.address() == rhs.address();
}
bool operator!=(ExternalReference lhs, ExternalReference rhs) {
return !(lhs == rhs);
}
size_t hash_value(ExternalReference reference) {
return base::hash<Address>()(reference.address());
}
std::ostream& operator<<(std::ostream& os, ExternalReference reference) {
os << static_cast<const void*>(reference.address());
const Runtime::Function* fn = Runtime::FunctionForEntry(reference.address());
if (fn) os << "<" << fn->name << ".entry>";
return os;
}
void PositionsRecorder::RecordPosition(int pos) {
DCHECK(pos != RelocInfo::kNoPosition);
DCHECK(pos >= 0);
......
......@@ -959,14 +959,6 @@ class ExternalReference BASE_EMBEDDED {
static ExternalReference stress_deopt_count(Isolate* isolate);
bool operator==(const ExternalReference& other) const {
return address_ == other.address_;
}
bool operator!=(const ExternalReference& other) const {
return !(*this == other);
}
private:
explicit ExternalReference(void* address)
: address_(address) {}
......@@ -987,6 +979,13 @@ class ExternalReference BASE_EMBEDDED {
void* address_;
};
bool operator==(ExternalReference, ExternalReference);
bool operator!=(ExternalReference, ExternalReference);
size_t hash_value(ExternalReference);
std::ostream& operator<<(std::ostream&, ExternalReference);
// -----------------------------------------------------------------------------
// Position recording support
......
......@@ -24,35 +24,51 @@ class ControlOperator : public Operator1<int> {
: Operator1<int>(opcode, properties, inputs, outputs, mnemonic,
controls) {}
virtual std::ostream& PrintParameter(std::ostream& os) const FINAL {
return os;
}
virtual void PrintParameter(std::ostream& os) const FINAL {}
};
} // namespace
// Specialization for static parameters of type {ExternalReference}.
template <>
struct StaticParameterTraits<ExternalReference> {
static std::ostream& PrintTo(std::ostream& os, ExternalReference reference) {
os << static_cast<const void*>(reference.address());
// TODO(bmeurer): Move to operator<<(os, ExternalReference)
const Runtime::Function* function =
Runtime::FunctionForEntry(reference.address());
if (function) {
os << " <" << function->name << ".entry>";
}
return os;
}
static int HashCode(ExternalReference reference) {
return bit_cast<int>(static_cast<uint32_t>(
reinterpret_cast<uintptr_t>(reference.address())));
}
static bool Equals(ExternalReference lhs, ExternalReference rhs) {
return lhs == rhs;
size_t hash_value(OutputFrameStateCombine const& sc) {
return base::hash_combine(sc.kind_, sc.parameter_);
}
std::ostream& operator<<(std::ostream& os, OutputFrameStateCombine const& sc) {
switch (sc.kind_) {
case OutputFrameStateCombine::kPushOutput:
if (sc.parameter_ == 0) return os << "Ignore";
return os << "Push(" << sc.parameter_ << ")";
case OutputFrameStateCombine::kPokeAt:
return os << "PokeAt(" << sc.parameter_ << ")";
}
};
UNREACHABLE();
return os;
}
bool operator==(FrameStateCallInfo const& lhs, FrameStateCallInfo const& rhs) {
return lhs.type() == rhs.type() && lhs.bailout_id() == rhs.bailout_id() &&
lhs.state_combine() == rhs.state_combine();
}
bool operator!=(FrameStateCallInfo const& lhs, FrameStateCallInfo const& rhs) {
return !(lhs == rhs);
}
size_t hash_value(FrameStateCallInfo const& info) {
return base::hash_combine(info.type(), info.bailout_id(),
info.state_combine());
}
std::ostream& operator<<(std::ostream& os, FrameStateCallInfo const& info) {
return os << info.type() << ", " << info.bailout_id() << ", "
<< info.state_combine();
}
#define SHARED_OP_LIST(V) \
......@@ -162,8 +178,8 @@ const Operator* CommonOperatorBuilder::NumberConstant(volatile double value) {
const Operator* CommonOperatorBuilder::HeapConstant(
const Unique<Object>& value) {
return new (zone()) Operator1<Unique<Object> >(
const Unique<HeapObject>& value) {
return new (zone()) Operator1<Unique<HeapObject>>(
IrOpcode::kHeapConstant, Operator::kPure, 0, 1, "HeapConstant", value);
}
......@@ -184,8 +200,8 @@ const Operator* CommonOperatorBuilder::EffectPhi(int arguments) {
const Operator* CommonOperatorBuilder::ValueEffect(int arguments) {
DCHECK(arguments > 0); // Disallow empty value effects.
return new (zone()) SimpleOperator(IrOpcode::kValueEffect, Operator::kPure,
arguments, 0, "ValueEffect");
return new (zone()) Operator1<int>(IrOpcode::kValueEffect, Operator::kPure,
arguments, 0, "ValueEffect", arguments);
}
......@@ -224,8 +240,8 @@ const Operator* CommonOperatorBuilder::Call(const CallDescriptor* descriptor) {
static_cast<int>(descriptor->ReturnCount()), mnemonic,
descriptor) {}
virtual std::ostream& PrintParameter(std::ostream& os) const OVERRIDE {
return os << "[" << *parameter() << "]";
virtual void PrintParameter(std::ostream& os) const OVERRIDE {
os << "[" << *parameter() << "]";
}
};
return new (zone()) CallOperator(descriptor, "Call");
......@@ -237,50 +253,6 @@ const Operator* CommonOperatorBuilder::Projection(size_t index) {
1, 1, "Projection", index);
}
OutputFrameStateCombine::OutputFrameStateCombine(CombineKind kind,
size_t parameter)
: kind_(kind), parameter_(parameter) {}
// static
OutputFrameStateCombine OutputFrameStateCombine::Ignore() {
return OutputFrameStateCombine(kPushOutput, 0);
}
// static
OutputFrameStateCombine OutputFrameStateCombine::Push(size_t count) {
return OutputFrameStateCombine(kPushOutput, count);
}
// static
OutputFrameStateCombine OutputFrameStateCombine::PokeAt(size_t index) {
return OutputFrameStateCombine(kPokeAt, index);
}
OutputFrameStateCombine::CombineKind OutputFrameStateCombine::kind() {
return kind_;
}
size_t OutputFrameStateCombine::GetPushCount() {
DCHECK(kind() == kPushOutput);
return parameter_;
}
size_t OutputFrameStateCombine::GetOffsetToPokeAt() {
DCHECK(kind() == kPokeAt);
return parameter_;
}
bool OutputFrameStateCombine::IsOutputIgnored() {
return kind() == kPushOutput && GetPushCount() == 0;
}
} // namespace compiler
} // namespace internal
} // namespace v8
......@@ -27,27 +27,53 @@ class Operator;
// the output of a node to obtain a framestate for lazy bailout.
class OutputFrameStateCombine {
public:
enum CombineKind {
enum Kind {
kPushOutput, // Push the output on the expression stack.
kPokeAt // Poke at the given environment location,
// counting from the top of the stack.
};
static OutputFrameStateCombine Ignore();
static OutputFrameStateCombine Push(size_t count = 1);
static OutputFrameStateCombine PokeAt(size_t index);
CombineKind kind();
size_t GetPushCount();
size_t GetOffsetToPokeAt();
bool IsOutputIgnored();
static OutputFrameStateCombine Ignore() {
return OutputFrameStateCombine(kPushOutput, 0);
}
static OutputFrameStateCombine Push(size_t count = 1) {
return OutputFrameStateCombine(kPushOutput, count);
}
static OutputFrameStateCombine PokeAt(size_t index) {
return OutputFrameStateCombine(kPokeAt, index);
}
Kind kind() const { return kind_; }
size_t GetPushCount() const {
DCHECK_EQ(kPushOutput, kind());
return parameter_;
}
size_t GetOffsetToPokeAt() const {
DCHECK_EQ(kPokeAt, kind());
return parameter_;
}
bool IsOutputIgnored() const {
return kind_ == kPushOutput && parameter_ == 0;
}
bool operator==(OutputFrameStateCombine const& other) const {
return kind_ == other.kind_ && parameter_ == other.parameter_;
}
bool operator!=(OutputFrameStateCombine const& other) const {
return !(*this == other);
}
friend size_t hash_value(OutputFrameStateCombine const&);
friend std::ostream& operator<<(std::ostream&,
OutputFrameStateCombine const&);
private:
OutputFrameStateCombine(CombineKind kind, size_t parameter);
OutputFrameStateCombine(Kind kind, size_t parameter)
: kind_(kind), parameter_(parameter) {}
CombineKind kind_;
size_t parameter_;
Kind const kind_;
size_t const parameter_;
};
......@@ -81,6 +107,13 @@ class FrameStateCallInfo FINAL {
MaybeHandle<JSFunction> jsfunction_;
};
bool operator==(FrameStateCallInfo const&, FrameStateCallInfo const&);
bool operator!=(FrameStateCallInfo const&, FrameStateCallInfo const&);
size_t hash_value(FrameStateCallInfo const&);
std::ostream& operator<<(std::ostream&, FrameStateCallInfo const&);
// Interface for building common operators that can be used at any level of IR,
// including JavaScript, mid-level, and low-level.
......@@ -107,7 +140,7 @@ class CommonOperatorBuilder FINAL {
const Operator* Float64Constant(volatile double);
const Operator* ExternalConstant(const ExternalReference&);
const Operator* NumberConstant(volatile double);
const Operator* HeapConstant(const Unique<Object>&);
const Operator* HeapConstant(const Unique<HeapObject>&);
const Operator* Phi(MachineType type, int arguments);
const Operator* EffectPhi(int arguments);
......
......@@ -10,8 +10,8 @@ namespace v8 {
namespace internal {
namespace compiler {
Node* JSGraph::ImmovableHeapConstant(Handle<Object> object) {
Unique<Object> unique = Unique<Object>::CreateImmovable(object);
Node* JSGraph::ImmovableHeapConstant(Handle<HeapObject> object) {
Unique<HeapObject> unique = Unique<HeapObject>::CreateImmovable(object);
return NewNode(common()->HeapConstant(unique));
}
......@@ -93,13 +93,13 @@ Node* JSGraph::NaNConstant() {
}
Node* JSGraph::HeapConstant(Unique<Object> value) {
Node* JSGraph::HeapConstant(Unique<HeapObject> value) {
// TODO(turbofan): canonicalize heap constants using Unique<T>
return NewNode(common()->HeapConstant(value));
}
Node* JSGraph::HeapConstant(Handle<Object> value) {
Node* JSGraph::HeapConstant(Handle<HeapObject> value) {
// TODO(titzer): We could also match against the addresses of immortable
// immovables here, even without access to the heap, thus always
// canonicalizing references to them.
......@@ -107,7 +107,8 @@ Node* JSGraph::HeapConstant(Handle<Object> value) {
// TODO(turbofan): This is a work-around to make Unique::HashCode() work for
// value numbering. We need some sane way to compute a unique hash code for
// arbitrary handles here.
Unique<Object> unique(reinterpret_cast<Address>(*value.location()), value);
Unique<HeapObject> unique(reinterpret_cast<Address>(*value.location()),
value);
return HeapConstant(unique);
}
......@@ -128,7 +129,7 @@ Node* JSGraph::Constant(Handle<Object> value) {
} else if (value->IsTheHole()) {
return TheHoleConstant();
} else {
return HeapConstant(value);
return HeapConstant(Handle<HeapObject>::cast(value));
}
}
......
......@@ -46,11 +46,11 @@ class JSGraph : public ZoneObject {
// Creates a HeapConstant node, possibly canonicalized, without inspecting the
// object.
Node* HeapConstant(Unique<Object> value);
Node* HeapConstant(Unique<HeapObject> value);
// Creates a HeapConstant node, possibly canonicalized, and may access the
// heap to inspect the object.
Node* HeapConstant(Handle<Object> value);
Node* HeapConstant(Handle<HeapObject> value);
// Creates a Constant node of the appropriate type for the given object.
// Accesses the heap to inspect the object and determine whether one of the
......@@ -109,7 +109,7 @@ class JSGraph : public ZoneObject {
CommonNodeCache cache_;
Node* ImmovableHeapConstant(Handle<Object> value);
Node* ImmovableHeapConstant(Handle<HeapObject> value);
Node* NumberConstant(double value);
Node* NewNode(const Operator* op);
......
......@@ -14,12 +14,56 @@ namespace v8 {
namespace internal {
namespace compiler {
bool operator==(CallFunctionParameters const& lhs,
CallFunctionParameters const& rhs) {
return lhs.arity() == rhs.arity() && lhs.flags() == rhs.flags();
}
bool operator!=(CallFunctionParameters const& lhs,
CallFunctionParameters const& rhs) {
return !(lhs == rhs);
}
size_t hash_value(CallFunctionParameters const& p) {
return base::hash_combine(p.arity(), p.flags());
}
std::ostream& operator<<(std::ostream& os, CallFunctionParameters const& p) {
return os << p.arity() << ", " << p.flags();
}
const CallFunctionParameters& CallFunctionParametersOf(const Operator* op) {
DCHECK_EQ(IrOpcode::kJSCallFunction, op->opcode());
return OpParameter<CallFunctionParameters>(op);
}
bool operator==(CallRuntimeParameters const& lhs,
CallRuntimeParameters const& rhs) {
return lhs.id() == rhs.id() && lhs.arity() == rhs.arity();
}
bool operator!=(CallRuntimeParameters const& lhs,
CallRuntimeParameters const& rhs) {
return !(lhs == rhs);
}
size_t hash_value(CallRuntimeParameters const& p) {
return base::hash_combine(p.id(), p.arity());
}
std::ostream& operator<<(std::ostream& os, CallRuntimeParameters const& p) {
return os << p.id() << ", " << p.arity();
}
const CallRuntimeParameters& CallRuntimeParametersOf(const Operator* op) {
DCHECK_EQ(IrOpcode::kJSCallRuntime, op->opcode());
return OpParameter<CallRuntimeParameters>(op);
......@@ -35,64 +79,90 @@ ContextAccess::ContextAccess(size_t depth, size_t index, bool immutable)
}
bool operator==(const ContextAccess& lhs, const ContextAccess& rhs) {
bool operator==(ContextAccess const& lhs, ContextAccess const& rhs) {
return lhs.depth() == rhs.depth() && lhs.index() == rhs.index() &&
lhs.immutable() == rhs.immutable();
}
bool operator!=(const ContextAccess& lhs, const ContextAccess& rhs) {
bool operator!=(ContextAccess const& lhs, ContextAccess const& rhs) {
return !(lhs == rhs);
}
const ContextAccess& ContextAccessOf(const Operator* op) {
size_t hash_value(ContextAccess const& access) {
return base::hash_combine(access.depth(), access.index(), access.immutable());
}
std::ostream& operator<<(std::ostream& os, ContextAccess const& access) {
return os << access.depth() << ", " << access.index() << ", "
<< access.immutable();
}
ContextAccess const& ContextAccessOf(Operator const* op) {
DCHECK(op->opcode() == IrOpcode::kJSLoadContext ||
op->opcode() == IrOpcode::kJSStoreContext);
return OpParameter<ContextAccess>(op);
}
bool operator==(LoadNamedParameters const& lhs,
LoadNamedParameters const& rhs) {
return lhs.name() == rhs.name() &&
lhs.contextual_mode() == rhs.contextual_mode();
}
bool operator!=(LoadNamedParameters const& lhs,
LoadNamedParameters const& rhs) {
return !(lhs == rhs);
}
size_t hash_value(LoadNamedParameters const& p) {
return base::hash_combine(p.name(), p.contextual_mode());
}
std::ostream& operator<<(std::ostream& os, LoadNamedParameters const& p) {
return os << Brief(*p.name().handle()) << ", " << p.contextual_mode();
}
const LoadNamedParameters& LoadNamedParametersOf(const Operator* op) {
DCHECK_EQ(IrOpcode::kJSLoadNamed, op->opcode());
return OpParameter<LoadNamedParameters>(op);
}
const StoreNamedParameters& StoreNamedParametersOf(const Operator* op) {
DCHECK_EQ(IrOpcode::kJSStoreNamed, op->opcode());
return OpParameter<StoreNamedParameters>(op);
bool operator==(StoreNamedParameters const& lhs,
StoreNamedParameters const& rhs) {
return lhs.strict_mode() == rhs.strict_mode() && lhs.name() == rhs.name();
}
// Specialization for static parameters of type {ContextAccess}.
template <>
struct StaticParameterTraits<ContextAccess> {
static std::ostream& PrintTo(std::ostream& os, const ContextAccess& access) {
return os << access.depth() << "," << access.index()
<< (access.immutable() ? ",imm" : "");
}
static int HashCode(const ContextAccess& access) {
return static_cast<int>((access.depth() << 16) | (access.index() & 0xffff));
}
static bool Equals(const ContextAccess& lhs, const ContextAccess& rhs) {
return lhs == rhs;
}
};
bool operator!=(StoreNamedParameters const& lhs,
StoreNamedParameters const& rhs) {
return !(lhs == rhs);
}
// Specialization for static parameters of type {Runtime::FunctionId}.
template <>
struct StaticParameterTraits<Runtime::FunctionId> {
static std::ostream& PrintTo(std::ostream& os, Runtime::FunctionId val) {
const Runtime::Function* f = Runtime::FunctionForId(val);
return os << (f->name ? f->name : "?Runtime?");
}
static int HashCode(Runtime::FunctionId val) { return static_cast<int>(val); }
static bool Equals(Runtime::FunctionId a, Runtime::FunctionId b) {
return a == b;
}
};
size_t hash_value(StoreNamedParameters const& p) {
return base::hash_combine(p.strict_mode(), p.name());
}
std::ostream& operator<<(std::ostream& os, StoreNamedParameters const& p) {
return os << p.strict_mode() << ", " << Brief(*p.name().handle());
}
const StoreNamedParameters& StoreNamedParametersOf(const Operator* op) {
DCHECK_EQ(IrOpcode::kJSStoreNamed, op->opcode());
return OpParameter<StoreNamedParameters>(op);
}
#define SHARED_OP_LIST(V) \
......@@ -241,9 +311,9 @@ const Operator* JSOperatorBuilder::StoreContext(size_t depth, size_t index) {
const Operator* JSOperatorBuilder::CreateCatchContext(
const Unique<String>& name) {
return new (zone()) Operator1<Unique<String> >(
IrOpcode::kJSCreateCatchContext, Operator::kNoProperties, 1, 1,
"JSCreateCatchContext", name);
return new (zone()) Operator1<Unique<String>>(IrOpcode::kJSCreateCatchContext,
Operator::kNoProperties, 1, 1,
"JSCreateCatchContext", name);
}
} // namespace compiler
......
......@@ -32,6 +32,13 @@ class CallFunctionParameters FINAL {
const CallFunctionFlags flags_;
};
bool operator==(CallFunctionParameters const&, CallFunctionParameters const&);
bool operator!=(CallFunctionParameters const&, CallFunctionParameters const&);
size_t hash_value(CallFunctionParameters const&);
std::ostream& operator<<(std::ostream&, CallFunctionParameters const&);
const CallFunctionParameters& CallFunctionParametersOf(const Operator* op);
......@@ -50,6 +57,13 @@ class CallRuntimeParameters FINAL {
const size_t arity_;
};
bool operator==(CallRuntimeParameters const&, CallRuntimeParameters const&);
bool operator!=(CallRuntimeParameters const&, CallRuntimeParameters const&);
size_t hash_value(CallRuntimeParameters const&);
std::ostream& operator<<(std::ostream&, CallRuntimeParameters const&);
const CallRuntimeParameters& CallRuntimeParametersOf(const Operator* op);
......@@ -72,10 +86,14 @@ class ContextAccess FINAL {
const uint32_t index_;
};
bool operator==(const ContextAccess& lhs, const ContextAccess& rhs);
bool operator!=(const ContextAccess& lhs, const ContextAccess& rhs);
bool operator==(ContextAccess const&, ContextAccess const&);
bool operator!=(ContextAccess const&, ContextAccess const&);
size_t hash_value(ContextAccess const&);
const ContextAccess& ContextAccessOf(const Operator* op);
std::ostream& operator<<(std::ostream&, ContextAccess const&);
ContextAccess const& ContextAccessOf(Operator const*);
// Defines the property being loaded from an object by a named load. This is
......@@ -93,6 +111,13 @@ class LoadNamedParameters FINAL {
const ContextualMode contextual_mode_;
};
bool operator==(LoadNamedParameters const&, LoadNamedParameters const&);
bool operator!=(LoadNamedParameters const&, LoadNamedParameters const&);
size_t hash_value(LoadNamedParameters const&);
std::ostream& operator<<(std::ostream&, LoadNamedParameters const&);
const LoadNamedParameters& LoadNamedParametersOf(const Operator* op);
......@@ -111,6 +136,13 @@ class StoreNamedParameters FINAL {
const Unique<Name> name_;
};
bool operator==(StoreNamedParameters const&, StoreNamedParameters const&);
bool operator!=(StoreNamedParameters const&, StoreNamedParameters const&);
size_t hash_value(StoreNamedParameters const&);
std::ostream& operator<<(std::ostream&, StoreNamedParameters const&);
const StoreNamedParameters& StoreNamedParametersOf(const Operator* op);
......
......@@ -12,9 +12,8 @@ namespace v8 {
namespace internal {
namespace compiler {
std::ostream& operator<<(std::ostream& os,
const WriteBarrierKind& write_barrier_kind) {
switch (write_barrier_kind) {
std::ostream& operator<<(std::ostream& os, WriteBarrierKind kind) {
switch (kind) {
case kNoWriteBarrier:
return os << "NoWriteBarrier";
case kFullWriteBarrier:
......@@ -25,39 +24,26 @@ std::ostream& operator<<(std::ostream& os,
}
std::ostream& operator<<(std::ostream& os, const StoreRepresentation& rep) {
return os << "(" << rep.machine_type() << " : " << rep.write_barrier_kind()
<< ")";
bool operator==(StoreRepresentation lhs, StoreRepresentation rhs) {
return lhs.machine_type() == rhs.machine_type() &&
lhs.write_barrier_kind() == rhs.write_barrier_kind();
}
template <>
struct StaticParameterTraits<StoreRepresentation> {
static std::ostream& PrintTo(std::ostream& os,
const StoreRepresentation& rep) {
return os << rep;
}
static int HashCode(const StoreRepresentation& rep) {
return rep.machine_type() + rep.write_barrier_kind();
}
static bool Equals(const StoreRepresentation& rep1,
const StoreRepresentation& rep2) {
return rep1 == rep2;
}
};
bool operator!=(StoreRepresentation lhs, StoreRepresentation rhs) {
return !(lhs == rhs);
}
template <>
struct StaticParameterTraits<LoadRepresentation> {
static std::ostream& PrintTo(std::ostream& os,
LoadRepresentation type) { // NOLINT
return os << type;
}
static int HashCode(LoadRepresentation type) { return type; }
static bool Equals(LoadRepresentation lhs, LoadRepresentation rhs) {
return lhs == rhs;
}
};
size_t hash_value(StoreRepresentation rep) {
return base::hash_combine(rep.machine_type(), rep.write_barrier_kind());
}
std::ostream& operator<<(std::ostream& os, StoreRepresentation rep) {
return os << "(" << rep.machine_type() << " : " << rep.write_barrier_kind()
<< ")";
}
#define PURE_OP_LIST(V) \
......
......@@ -19,15 +19,15 @@ class Operator;
// Supported write barrier modes.
enum WriteBarrierKind { kNoWriteBarrier, kFullWriteBarrier };
std::ostream& operator<<(std::ostream& os,
const WriteBarrierKind& write_barrier_kind);
std::ostream& operator<<(std::ostream& os, WriteBarrierKind);
// A Load needs a MachineType.
typedef MachineType LoadRepresentation;
// A Store needs a MachineType and a WriteBarrierKind
// in order to emit the correct write barrier.
// A Store needs a MachineType and a WriteBarrierKind in order to emit the
// correct write barrier.
class StoreRepresentation FINAL {
public:
StoreRepresentation(MachineType machine_type,
......@@ -42,18 +42,12 @@ class StoreRepresentation FINAL {
WriteBarrierKind write_barrier_kind_;
};
inline bool operator==(const StoreRepresentation& rep1,
const StoreRepresentation& rep2) {
return rep1.machine_type() == rep2.machine_type() &&
rep1.write_barrier_kind() == rep2.write_barrier_kind();
}
bool operator==(StoreRepresentation, StoreRepresentation);
bool operator!=(StoreRepresentation, StoreRepresentation);
inline bool operator!=(const StoreRepresentation& rep1,
const StoreRepresentation& rep2) {
return !(rep1 == rep2);
}
size_t hash_value(StoreRepresentation);
std::ostream& operator<<(std::ostream& os, const StoreRepresentation& rep);
std::ostream& operator<<(std::ostream&, StoreRepresentation);
// Interface for building machine-level operators. These operators are
......
......@@ -7,6 +7,7 @@
#include "src/compiler/node.h"
#include "src/compiler/operator.h"
#include "src/unique.h"
namespace v8 {
namespace internal {
......
......@@ -42,11 +42,6 @@ Node* Node::FindProjection(size_t projection_index) {
}
std::ostream& operator<<(std::ostream& os, const Operator& op) {
return op.PrintTo(os);
}
std::ostream& operator<<(std::ostream& os, const Node& n) {
os << n.id() << ": " << *n.op();
if (n.op()->InputCount() != 0) {
......
......@@ -4,6 +4,8 @@
#include "src/compiler/operator.h"
#include <limits>
namespace v8 {
namespace internal {
namespace compiler {
......@@ -11,16 +13,44 @@ namespace compiler {
Operator::~Operator() {}
std::ostream& operator<<(std::ostream& os, const Operator& op) {
op.PrintTo(os);
return os;
}
SimpleOperator::SimpleOperator(Opcode opcode, Properties properties,
int input_count, int output_count,
size_t input_count, size_t output_count,
const char* mnemonic)
: Operator(opcode, properties, mnemonic),
input_count_(input_count),
output_count_(output_count) {}
input_count_(static_cast<uint8_t>(input_count)),
output_count_(static_cast<uint8_t>(output_count)) {
DCHECK(input_count <= std::numeric_limits<uint8_t>::max());
DCHECK(output_count <= std::numeric_limits<uint8_t>::max());
}
SimpleOperator::~SimpleOperator() {}
bool SimpleOperator::Equals(const Operator* that) const {
return opcode() == that->opcode();
}
size_t SimpleOperator::HashCode() const {
return base::hash<Opcode>()(opcode());
}
int SimpleOperator::InputCount() const { return input_count_; }
int SimpleOperator::OutputCount() const { return output_count_; }
void SimpleOperator::PrintTo(std::ostream& os) const { os << mnemonic(); }
} // namespace compiler
} // namespace internal
} // namespace v8
......@@ -5,9 +5,11 @@
#ifndef V8_COMPILER_OPERATOR_H_
#define V8_COMPILER_OPERATOR_H_
#include <ostream> // NOLINT(readability/streams)
#include "src/base/flags.h"
#include "src/ostreams.h"
#include "src/unique.h"
#include "src/base/functional.h"
#include "src/zone.h"
namespace v8 {
namespace internal {
......@@ -63,12 +65,12 @@ class Operator : public ZoneObject {
// Check if this operator equals another operator. Equivalent operators can
// be merged, and nodes with equivalent operators and equivalent inputs
// can be merged.
virtual bool Equals(const Operator* other) const = 0;
virtual bool Equals(const Operator*) const = 0;
// Compute a hashcode to speed up equivalence-set checking.
// Equal operators should always have equal hashcodes, and unequal operators
// should have unequal hashcodes with high probability.
virtual int HashCode() const = 0;
virtual size_t HashCode() const = 0;
// Check whether this operator has the given property.
bool HasProperty(Property property) const {
......@@ -87,7 +89,7 @@ class Operator : public ZoneObject {
protected:
// Print the full operator into the given stream, including any
// static parameters. Useful for debugging and visualizing the IR.
virtual std::ostream& PrintTo(std::ostream& os) const = 0; // NOLINT
virtual void PrintTo(std::ostream& os) const = 0; // NOLINT
friend std::ostream& operator<<(std::ostream& os, const Operator& op);
private:
......@@ -102,159 +104,82 @@ DEFINE_OPERATORS_FOR_FLAGS(Operator::Properties)
std::ostream& operator<<(std::ostream& os, const Operator& op);
// An implementation of Operator that has no static parameters. Such operators
// have just a name, an opcode, and a fixed number of inputs and outputs.
// They can represented by singletons and shared globally.
class SimpleOperator : public Operator {
public:
SimpleOperator(Opcode opcode, Properties properties, int input_count,
int output_count, const char* mnemonic);
SimpleOperator(Opcode opcode, Properties properties, size_t input_count,
size_t output_count, const char* mnemonic);
~SimpleOperator();
virtual bool Equals(const Operator* that) const FINAL {
return opcode() == that->opcode();
}
virtual int HashCode() const FINAL { return opcode(); }
virtual int InputCount() const FINAL { return input_count_; }
virtual int OutputCount() const FINAL { return output_count_; }
virtual bool Equals(const Operator* that) const FINAL;
virtual size_t HashCode() const FINAL;
virtual int InputCount() const FINAL;
virtual int OutputCount() const FINAL;
private:
virtual std::ostream& PrintTo(std::ostream& os) const FINAL { // NOLINT
return os << mnemonic();
}
virtual void PrintTo(std::ostream& os) const FINAL;
int input_count_;
int output_count_;
uint8_t input_count_;
uint8_t output_count_;
DISALLOW_COPY_AND_ASSIGN(SimpleOperator);
};
// Template specialization implements a kind of type class for dealing with the
// static parameters of Operator1 automatically.
template <typename T>
struct StaticParameterTraits {
static std::ostream& PrintTo(std::ostream& os, T val) { // NOLINT
return os << "??";
}
static int HashCode(T a) { return 0; }
static bool Equals(T a, T b) {
return false; // Not every T has a ==. By default, be conservative.
}
};
// Specialization for static parameters of type {int}.
template <>
struct StaticParameterTraits<int> {
static std::ostream& PrintTo(std::ostream& os, int val) { // NOLINT
return os << val;
}
static int HashCode(int a) { return a; }
static bool Equals(int a, int b) { return a == b; }
};
// Specialization for static parameters of type {double}.
template <>
struct StaticParameterTraits<double> {
static std::ostream& PrintTo(std::ostream& os, double val) { // NOLINT
return os << val;
}
static int HashCode(double a) {
return static_cast<int>(bit_cast<int64_t>(a));
}
static bool Equals(double a, double b) {
return bit_cast<int64_t>(a) == bit_cast<int64_t>(b);
}
};
// Specialization for static parameters of type {Unique<Object>}.
template <>
struct StaticParameterTraits<Unique<Object> > {
static std::ostream& PrintTo(std::ostream& os,
Unique<Object> val) { // NOLINT
return os << Brief(*val.handle());
}
static int HashCode(Unique<Object> a) {
return static_cast<int>(a.Hashcode());
}
static bool Equals(Unique<Object> a, Unique<Object> b) { return a == b; }
};
// Specialization for static parameters of type {Unique<Name>}.
template <>
struct StaticParameterTraits<Unique<Name> > {
static std::ostream& PrintTo(std::ostream& os, Unique<Name> val) { // NOLINT
return os << Brief(*val.handle());
}
static int HashCode(Unique<Name> a) { return static_cast<int>(a.Hashcode()); }
static bool Equals(Unique<Name> a, Unique<Name> b) { return a == b; }
};
#if DEBUG
// Specialization for static parameters of type {Handle<Object>} to prevent any
// direct usage of Handles in constants.
template <>
struct StaticParameterTraits<Handle<Object> > {
static std::ostream& PrintTo(std::ostream& os,
Handle<Object> val) { // NOLINT
UNREACHABLE(); // Should use Unique<Object> instead
return os;
}
static int HashCode(Handle<Object> a) {
UNREACHABLE(); // Should use Unique<Object> instead
return 0;
}
static bool Equals(Handle<Object> a, Handle<Object> b) {
UNREACHABLE(); // Should use Unique<Object> instead
return false;
}
};
#endif
// A templatized implementation of Operator that has one static parameter of
// type {T}. If a specialization of StaticParameterTraits<{T}> exists, then
// operators of this kind can automatically be hashed, compared, and printed.
template <typename T>
// type {T}.
template <typename T, typename Pred = std::equal_to<T>,
typename Hash = base::hash<T>>
class Operator1 : public Operator {
public:
Operator1(Opcode opcode, Properties properties, int input_count,
int output_count, const char* mnemonic, T parameter)
int output_count, const char* mnemonic, T parameter,
Pred const& pred = Pred(), Hash const& hash = Hash())
: Operator(opcode, properties, mnemonic),
input_count_(input_count),
output_count_(output_count),
parameter_(parameter) {}
parameter_(parameter),
pred_(pred),
hash_(hash) {}
const T& parameter() const { return parameter_; }
T const& parameter() const { return parameter_; }
virtual bool Equals(const Operator* other) const OVERRIDE {
virtual bool Equals(const Operator* other) const FINAL {
if (opcode() != other->opcode()) return false;
const Operator1<T>* that = static_cast<const Operator1<T>*>(other);
return StaticParameterTraits<T>::Equals(this->parameter_, that->parameter_);
return this->pred_(this->parameter(), that->parameter());
}
virtual int HashCode() const OVERRIDE {
return opcode() + 33 * StaticParameterTraits<T>::HashCode(this->parameter_);
virtual size_t HashCode() const FINAL {
return base::hash_combine(this->opcode(), this->hash_(this->parameter()));
}
virtual int InputCount() const OVERRIDE { return input_count_; }
virtual int OutputCount() const OVERRIDE { return output_count_; }
virtual std::ostream& PrintParameter(std::ostream& os) const { // NOLINT
return StaticParameterTraits<T>::PrintTo(os << "[", parameter_) << "]";
virtual int InputCount() const FINAL { return input_count_; }
virtual int OutputCount() const FINAL { return output_count_; }
virtual void PrintParameter(std::ostream& os) const {
os << "[" << this->parameter() << "]";
}
protected:
virtual std::ostream& PrintTo(std::ostream& os) const FINAL { // NOLINT
return PrintParameter(os << mnemonic());
virtual void PrintTo(std::ostream& os) const FINAL {
os << mnemonic();
PrintParameter(os);
}
private:
int input_count_;
int output_count_;
T parameter_;
int const input_count_;
int const output_count_;
T const parameter_;
Pred const pred_;
Hash const hash_;
};
// Helper to extract parameters from Operator1<*> operator.
template <typename T>
static inline const T& OpParameter(const Operator* op) {
return reinterpret_cast<const Operator1<T>*>(op)->parameter();
inline T const& OpParameter(const Operator* op) {
return static_cast<const Operator1<T>*>(op)->parameter();
}
} // namespace compiler
......
......@@ -57,7 +57,7 @@ class RawMachineAssembler : public GraphBuilder {
MachineSignature* machine_sig() const { return machine_sig_; }
Node* UndefinedConstant() {
Unique<Object> unique = Unique<Object>::CreateImmovable(
Unique<HeapObject> unique = Unique<HeapObject>::CreateImmovable(
isolate()->factory()->undefined_value());
return NewNode(common()->HeapConstant(unique));
}
......@@ -86,8 +86,8 @@ class RawMachineAssembler : public GraphBuilder {
Node* Float64Constant(double value) {
return NewNode(common()->Float64Constant(value));
}
Node* HeapConstant(Handle<Object> object) {
Unique<Object> val = Unique<Object>::CreateUninitialized(object);
Node* HeapConstant(Handle<HeapObject> object) {
Unique<HeapObject> val = Unique<HeapObject>::CreateUninitialized(object);
return NewNode(common()->HeapConstant(val));
}
......
......@@ -4,8 +4,6 @@
#include "src/compiler/simplified-operator.h"
#include <ostream> // NOLINT(readability/streams)
#include "src/base/lazy-instance.h"
#include "src/compiler/opcodes.h"
#include "src/compiler/operator.h"
......@@ -29,7 +27,7 @@ std::ostream& operator<<(std::ostream& os, BaseTaggedness base_taggedness) {
bool operator==(FieldAccess const& lhs, FieldAccess const& rhs) {
return lhs.base_is_tagged == rhs.base_is_tagged && lhs.offset == rhs.offset &&
lhs.type == rhs.type && lhs.machine_type == rhs.machine_type;
lhs.machine_type == rhs.machine_type;
}
......@@ -38,6 +36,12 @@ bool operator!=(FieldAccess const& lhs, FieldAccess const& rhs) {
}
size_t hash_value(FieldAccess const& access) {
return base::hash_combine(access.base_is_tagged, access.offset,
access.machine_type);
}
std::ostream& operator<<(std::ostream& os, FieldAccess const& access) {
os << "[" << access.base_is_tagged << ", " << access.offset << ", ";
#ifdef OBJECT_PRINT
......@@ -67,7 +71,7 @@ std::ostream& operator<<(std::ostream& os, BoundsCheckMode bounds_check_mode) {
bool operator==(ElementAccess const& lhs, ElementAccess const& rhs) {
return lhs.base_is_tagged == rhs.base_is_tagged &&
lhs.header_size == rhs.header_size && lhs.type == rhs.type &&
lhs.header_size == rhs.header_size &&
lhs.machine_type == rhs.machine_type;
}
......@@ -77,10 +81,16 @@ bool operator!=(ElementAccess const& lhs, ElementAccess const& rhs) {
}
size_t hash_value(ElementAccess const& access) {
return base::hash_combine(access.base_is_tagged, access.header_size,
access.machine_type);
}
std::ostream& operator<<(std::ostream& os, ElementAccess const& access) {
os << "[" << access.base_is_tagged << ", " << access.header_size << ", ";
os << access.base_is_tagged << ", " << access.header_size << ", ";
access.type->PrintTo(os);
os << ", " << access.machine_type << ", " << access.bounds_check << "]";
os << ", " << access.machine_type << ", " << access.bounds_check;
return os;
}
......@@ -101,40 +111,6 @@ const ElementAccess& ElementAccessOf(const Operator* op) {
}
// Specialization for static parameters of type {FieldAccess}.
template <>
struct StaticParameterTraits<FieldAccess> {
static std::ostream& PrintTo(std::ostream& os, const FieldAccess& val) {
return os << val.offset;
}
static int HashCode(const FieldAccess& val) {
return (val.offset < 16) | (val.machine_type & 0xffff);
}
static bool Equals(const FieldAccess& lhs, const FieldAccess& rhs) {
return lhs.base_is_tagged == rhs.base_is_tagged &&
lhs.offset == rhs.offset && lhs.machine_type == rhs.machine_type &&
lhs.type->Is(rhs.type);
}
};
// Specialization for static parameters of type {ElementAccess}.
template <>
struct StaticParameterTraits<ElementAccess> {
static std::ostream& PrintTo(std::ostream& os, const ElementAccess& access) {
return os << access;
}
static int HashCode(const ElementAccess& access) {
return (access.header_size < 16) | (access.machine_type & 0xffff);
}
static bool Equals(const ElementAccess& lhs, const ElementAccess& rhs) {
return lhs.base_is_tagged == rhs.base_is_tagged &&
lhs.header_size == rhs.header_size &&
lhs.machine_type == rhs.machine_type && lhs.type->Is(rhs.type);
}
};
#define PURE_OP_LIST(V) \
V(BooleanNot, Operator::kNoProperties, 1) \
V(BooleanToNumber, Operator::kNoProperties, 1) \
......
......@@ -32,6 +32,7 @@ enum BaseTaggedness { kUntaggedBase, kTaggedBase };
std::ostream& operator<<(std::ostream&, BaseTaggedness);
// An access descriptor for loads/stores of fixed structures like field
// accesses of heap objects. Accesses from either tagged or untagged base
// pointers are supported; untagging is done automatically during lowering.
......@@ -45,12 +46,15 @@ struct FieldAccess {
int tag() const { return base_is_tagged == kTaggedBase ? kHeapObjectTag : 0; }
};
bool operator==(FieldAccess const& lhs, FieldAccess const& rhs);
bool operator!=(FieldAccess const& lhs, FieldAccess const& rhs);
bool operator==(FieldAccess const&, FieldAccess const&);
bool operator!=(FieldAccess const&, FieldAccess const&);
size_t hash_value(FieldAccess const&);
std::ostream& operator<<(std::ostream&, FieldAccess const&);
// The bound checking mode for ElementAccess below.
enum BoundsCheckMode { kNoBoundsCheck, kTypedArrayBoundsCheck };
std::ostream& operator<<(std::ostream&, BoundsCheckMode);
......@@ -70,8 +74,10 @@ struct ElementAccess {
int tag() const { return base_is_tagged == kTaggedBase ? kHeapObjectTag : 0; }
};
bool operator==(ElementAccess const& lhs, ElementAccess const& rhs);
bool operator!=(ElementAccess const& lhs, ElementAccess const& rhs);
bool operator==(ElementAccess const&, ElementAccess const&);
bool operator!=(ElementAccess const&, ElementAccess const&);
size_t hash_value(ElementAccess const&);
std::ostream& operator<<(std::ostream&, ElementAccess const&);
......
......@@ -3318,5 +3318,11 @@ const Runtime::Function* Runtime::FunctionForEntry(Address entry) {
const Runtime::Function* Runtime::FunctionForId(Runtime::FunctionId id) {
return &(kIntrinsicFunctions[static_cast<int>(id)]);
}
std::ostream& operator<<(std::ostream& os, Runtime::FunctionId id) {
return os << Runtime::FunctionForId(id)->name;
}
} // namespace v8::internal
} // namespace internal
} // namespace v8
......@@ -898,6 +898,8 @@ class Runtime : public AllStatic {
};
std::ostream& operator<<(std::ostream&, Runtime::FunctionId);
//---------------------------------------------------------------------------
// Constants used by interface to runtime functions.
......@@ -907,7 +909,8 @@ class AllocateTargetSpace : public BitField<AllocationSpace, 1, 3> {};
class DeclareGlobalsEvalFlag : public BitField<bool, 0, 1> {};
class DeclareGlobalsNativeFlag : public BitField<bool, 1, 1> {};
class DeclareGlobalsStrictMode : public BitField<StrictMode, 2, 1> {};
}
} // namespace v8::internal
} // namespace internal
} // namespace v8
#endif // V8_RUNTIME_H_
......@@ -5,9 +5,11 @@
#ifndef V8_HYDROGEN_UNIQUE_H_
#define V8_HYDROGEN_UNIQUE_H_
#include <ostream> // NOLINT(readability/streams)
#include "src/base/functional.h"
#include "src/handles-inl.h" // TODO(everyone): Fix our inl.h crap
#include "src/objects-inl.h" // TODO(everyone): Fix our inl.h crap
#include "src/string-stream.h"
#include "src/utils.h"
#include "src/zone.h"
......@@ -81,6 +83,11 @@ class Unique {
return raw_address_ != other.raw_address_;
}
friend inline size_t hash_value(Unique<T> const& unique) {
DCHECK(unique.IsInitialized());
return base::hash<void*>()(unique.raw_address_);
}
inline intptr_t Hashcode() const {
DCHECK(IsInitialized());
return reinterpret_cast<intptr_t>(raw_address_);
......@@ -128,6 +135,11 @@ class Unique {
friend class SideEffectsTracker;
};
template <typename T>
inline std::ostream& operator<<(std::ostream& os, Unique<T> uniq) {
return os << Brief(*uniq.handle());
}
template <typename T>
class UniqueSet FINAL : public ZoneObject {
......
......@@ -7,6 +7,7 @@
#include "src/v8.h"
#include "src/base/functional.h"
#include "src/base/logging.h"
#include "src/base/platform/platform.h"
#include "src/utils.h"
......@@ -77,6 +78,17 @@ char* SimpleStringBuilder::Finalize() {
}
size_t hash_value(BailoutId id) {
base::hash<int> h;
return h(id.id_);
}
std::ostream& operator<<(std::ostream& os, BailoutId id) {
return os << id.id_;
}
void PrintF(const char* format, ...) {
va_list arguments;
va_start(arguments, format);
......
......@@ -965,6 +965,8 @@ class BailoutId {
bool IsNone() const { return id_ == kNoneId; }
bool operator==(const BailoutId& other) const { return id_ == other.id_; }
bool operator!=(const BailoutId& other) const { return id_ != other.id_; }
friend size_t hash_value(BailoutId);
friend std::ostream& operator<<(std::ostream&, BailoutId);
private:
static const int kNoneId = -1;
......
......@@ -477,10 +477,10 @@ TEST(RunHeapConstant) {
TEST(RunHeapNumberConstant) {
RawMachineAssemblerTester<Object*> m;
Handle<Object> number = m.isolate()->factory()->NewHeapNumber(100.5);
RawMachineAssemblerTester<HeapObject*> m;
Handle<HeapObject> number = m.isolate()->factory()->NewHeapNumber(100.5);
m.Return(m.HeapConstant(number));
Object* result = m.Call();
HeapObject* result = m.Call();
CHECK_EQ(result, *number);
}
......
......@@ -45,8 +45,8 @@ class SimplifiedGraphBuilder : public GraphBuilder {
Node* Int32Constant(int32_t value) {
return NewNode(common()->Int32Constant(value));
}
Node* HeapConstant(Handle<Object> object) {
Unique<Object> val = Unique<Object>::CreateUninitialized(object);
Node* HeapConstant(Handle<HeapObject> object) {
Unique<HeapObject> val = Unique<HeapObject>::CreateUninitialized(object);
return NewNode(common()->HeapConstant(val));
}
......
......@@ -129,13 +129,13 @@ class TrivialDeoptCodegenTester : public DeoptCodegenTester {
Handle<JSFunction> deopt_function =
NewFunction("function deopt() { %DeoptimizeFunction(foo); }; deopt");
Unique<Object> deopt_fun_constant =
Unique<Object>::CreateUninitialized(deopt_function);
Unique<JSFunction> deopt_fun_constant =
Unique<JSFunction>::CreateUninitialized(deopt_function);
Node* deopt_fun_node = m.NewNode(common.HeapConstant(deopt_fun_constant));
Handle<Context> caller_context(function->context(), CcTest::i_isolate());
Unique<Object> caller_context_constant =
Unique<Object>::CreateUninitialized(caller_context);
Unique<Context> caller_context_constant =
Unique<Context>::CreateUninitialized(caller_context);
Node* caller_context_node =
m.NewNode(common.HeapConstant(caller_context_constant));
......@@ -150,8 +150,8 @@ class TrivialDeoptCodegenTester : public DeoptCodegenTester {
parameters, locals, stack, caller_context_node, m.UndefinedConstant());
Handle<Context> context(deopt_function->context(), CcTest::i_isolate());
Unique<Object> context_constant =
Unique<Object>::CreateUninitialized(context);
Unique<Context> context_constant =
Unique<Context>::CreateUninitialized(context);
Node* context_node = m.NewNode(common.HeapConstant(context_constant));
m.CallJS0(deopt_fun_node, m.UndefinedConstant(), context_node, state_node);
......@@ -245,13 +245,13 @@ class TrivialRuntimeDeoptCodegenTester : public DeoptCodegenTester {
CSignature1<Object*, Object*> sig;
RawMachineAssembler m(graph, &sig);
Unique<Object> this_fun_constant =
Unique<Object>::CreateUninitialized(function);
Unique<HeapObject> this_fun_constant =
Unique<HeapObject>::CreateUninitialized(function);
Node* this_fun_node = m.NewNode(common.HeapConstant(this_fun_constant));
Handle<Context> context(function->context(), CcTest::i_isolate());
Unique<Object> context_constant =
Unique<Object>::CreateUninitialized(context);
Unique<HeapObject> context_constant =
Unique<HeapObject>::CreateUninitialized(context);
Node* context_node = m.NewNode(common.HeapConstant(context_constant));
bailout_id = GetCallBailoutId();
......
......@@ -49,13 +49,14 @@ class JSTypedLoweringTester : public HandleAndZoneScope {
}
Node* UndefinedConstant() {
Unique<Object> unique =
Unique<Object>::CreateImmovable(isolate->factory()->undefined_value());
Unique<HeapObject> unique = Unique<HeapObject>::CreateImmovable(
isolate->factory()->undefined_value());
return graph.NewNode(common.HeapConstant(unique));
}
Node* HeapConstant(Handle<Object> constant) {
Unique<Object> unique = Unique<Object>::CreateUninitialized(constant);
Node* HeapConstant(Handle<HeapObject> constant) {
Unique<HeapObject> unique =
Unique<HeapObject>::CreateUninitialized(constant);
return graph.NewNode(common.HeapConstant(unique));
}
......
......@@ -91,13 +91,13 @@ TEST(TestOperator1intHash) {
Operator1<int> op1a(23, Operator::kNoProperties, 0, 0, "Wolfie", 11);
Operator1<int> op1b(23, Operator::kFoldable, 2, 2, "Doggie", 11);
CHECK_EQ(op1a.HashCode(), op1b.HashCode());
CHECK(op1a.HashCode() == op1b.HashCode());
Operator1<int> op2a(24, Operator::kNoProperties, 0, 0, "Arfie", 3);
Operator1<int> op2b(24, Operator::kNoProperties, 0, 0, "Arfie", 4);
CHECK_NE(op1a.HashCode(), op2a.HashCode());
CHECK_NE(op2a.HashCode(), op2b.HashCode());
CHECK(op1a.HashCode() != op2a.HashCode());
CHECK(op2a.HashCode() != op2b.HashCode());
}
......@@ -161,13 +161,13 @@ TEST(TestOperator1doubleHash) {
Operator1<double> op1a(23, Operator::kNoProperties, 0, 0, "Wolfie", 11.77);
Operator1<double> op1b(23, Operator::kFoldable, 2, 2, "Doggie", 11.77);
CHECK_EQ(op1a.HashCode(), op1b.HashCode());
CHECK(op1a.HashCode() == op1b.HashCode());
Operator1<double> op2a(24, Operator::kNoProperties, 0, 0, "Arfie", -6.7);
Operator1<double> op2b(24, Operator::kNoProperties, 0, 0, "Arfie", -6.8);
CHECK_NE(op1a.HashCode(), op2a.HashCode());
CHECK_NE(op2a.HashCode(), op2b.HashCode());
CHECK(op1a.HashCode() != op2a.HashCode());
CHECK(op2a.HashCode() != op2b.HashCode());
}
......
......@@ -680,9 +680,10 @@ TEST(BuildScheduleIfSplitWithEffects) {
JSOperatorBuilder js_builder(scope.main_zone());
const Operator* op;
Handle<Object> object =
Handle<Object>(isolate->heap()->undefined_value(), isolate);
Unique<Object> unique_constant = Unique<Object>::CreateUninitialized(object);
Handle<HeapObject> object =
Handle<HeapObject>(isolate->heap()->undefined_value(), isolate);
Unique<HeapObject> unique_constant =
Unique<HeapObject>::CreateUninitialized(object);
// Manually transcripted code for:
// function turbo_fan_test(a, b, c, y) {
......@@ -825,9 +826,10 @@ TEST(BuildScheduleSimpleLoop) {
JSOperatorBuilder js_builder(scope.main_zone());
const Operator* op;
Handle<Object> object =
Handle<Object>(isolate->heap()->undefined_value(), isolate);
Unique<Object> unique_constant = Unique<Object>::CreateUninitialized(object);
Handle<HeapObject> object =
Handle<HeapObject>(isolate->heap()->undefined_value(), isolate);
Unique<HeapObject> unique_constant =
Unique<HeapObject>::CreateUninitialized(object);
// Manually transcripted code for:
// function turbo_fan_test(a, b) {
......@@ -937,9 +939,10 @@ TEST(BuildScheduleComplexLoops) {
JSOperatorBuilder js_builder(scope.main_zone());
const Operator* op;
Handle<Object> object =
Handle<Object>(isolate->heap()->undefined_value(), isolate);
Unique<Object> unique_constant = Unique<Object>::CreateUninitialized(object);
Handle<HeapObject> object =
Handle<HeapObject>(isolate->heap()->undefined_value(), isolate);
Unique<HeapObject> unique_constant =
Unique<HeapObject>::CreateUninitialized(object);
// Manually transcripted code for:
// function turbo_fan_test(a, b, c) {
......@@ -1184,9 +1187,10 @@ TEST(BuildScheduleBreakAndContinue) {
JSOperatorBuilder js_builder(scope.main_zone());
const Operator* op;
Handle<Object> object =
Handle<Object>(isolate->heap()->undefined_value(), isolate);
Unique<Object> unique_constant = Unique<Object>::CreateUninitialized(object);
Handle<HeapObject> object =
Handle<HeapObject>(isolate->heap()->undefined_value(), isolate);
Unique<HeapObject> unique_constant =
Unique<HeapObject>::CreateUninitialized(object);
// Manually transcripted code for:
// function turbo_fan_test(a, b, c) {
......@@ -1514,9 +1518,10 @@ TEST(BuildScheduleSimpleLoopWithCodeMotion) {
MachineOperatorBuilder machine_builder;
const Operator* op;
Handle<Object> object =
Handle<Object>(isolate->heap()->undefined_value(), isolate);
Unique<Object> unique_constant = Unique<Object>::CreateUninitialized(object);
Handle<HeapObject> object =
Handle<HeapObject>(isolate->heap()->undefined_value(), isolate);
Unique<HeapObject> unique_constant =
Unique<HeapObject>::CreateUninitialized(object);
// Manually transcripted code for:
// function turbo_fan_test(a, b, c) {
......
......@@ -17,18 +17,6 @@ using testing::StringMatchResultListener;
namespace v8 {
namespace internal {
// TODO(bmeurer): Find a new home for these functions.
template <typename T>
inline std::ostream& operator<<(std::ostream& os, const Unique<T>& value) {
return os << *value.handle();
}
inline std::ostream& operator<<(std::ostream& os,
const ExternalReference& value) {
compiler::StaticParameterTraits<ExternalReference>::PrintTo(os, value);
return os;
}
namespace compiler {
GraphTest::GraphTest(int num_parameters) : common_(zone()), graph_(zone()) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment