Commit 1021ed85 authored by bmeurer's avatar bmeurer Committed by Commit bot

[ubsan] Fix HeapObjectMatcher to avoid invalid casts.

BUG=v8:3809
LOG=n
R=svenpanne@chromium.org

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

Cr-Commit-Position: refs/heads/master@{#29147}
parent 733a2463
......@@ -3590,7 +3590,7 @@ Node* AstGraphBuilder::BuildToBoolean(Node* input) {
case IrOpcode::kNumberConstant:
return jsgraph_->BooleanConstant(!NumberMatcher(input).Is(0));
case IrOpcode::kHeapConstant: {
Handle<Object> object = HeapObjectMatcher<Object>(input).Value().handle();
Handle<HeapObject> object = HeapObjectMatcher(input).Value().handle();
return jsgraph_->BooleanConstant(object->BooleanValue());
}
case IrOpcode::kJSEqual:
......
......@@ -31,7 +31,7 @@ Decision DecideCondition(Node* const cond) {
return mcond.Value() ? Decision::kTrue : Decision::kFalse;
}
case IrOpcode::kHeapConstant: {
HeapObjectMatcher<HeapObject> mcond(cond);
HeapObjectMatcher mcond(cond);
return mcond.Value().handle()->BooleanValue() ? Decision::kTrue
: Decision::kFalse;
}
......
// 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.
#include "src/compiler/common-operator.h"
#include "src/compiler/common-operator-reducer.h"
#include "src/compiler/control-reducer.h"
#include "src/compiler/graph.h"
#include "src/compiler/graph-reducer.h"
#include "src/compiler/js-graph.h"
#include "src/compiler/node-marker.h"
#include "src/compiler/node-matchers.h"
#include "src/compiler/node-properties.h"
#include "src/zone-containers.h"
namespace v8 {
namespace internal {
namespace compiler {
#define TRACE(...) \
do { \
if (FLAG_trace_turbo_reduction) PrintF(__VA_ARGS__); \
} while (false)
enum Decision { kFalse, kUnknown, kTrue };
class ControlReducerImpl final : public AdvancedReducer {
public:
Zone* zone_;
JSGraph* jsgraph_;
int max_phis_for_select_;
ControlReducerImpl(Editor* editor, Zone* zone, JSGraph* jsgraph)
: AdvancedReducer(editor),
zone_(zone),
jsgraph_(jsgraph),
max_phis_for_select_(0) {}
Graph* graph() { return jsgraph_->graph(); }
CommonOperatorBuilder* common() { return jsgraph_->common(); }
Node* dead() { return jsgraph_->DeadControl(); }
//===========================================================================
// Reducer implementation: perform reductions on a node.
//===========================================================================
Reduction Reduce(Node* node) override {
if (node->op()->ControlInputCount() == 1 ||
node->opcode() == IrOpcode::kLoop) {
// If a node has only one control input and it is dead, replace with dead.
Node* control = NodeProperties::GetControlInput(node);
if (control->opcode() == IrOpcode::kDeadControl) {
TRACE("ControlDead: #%d:%s\n", node->id(), node->op()->mnemonic());
return Replace(control);
}
}
Node* result = node;
// Reduce branches, phis, and merges.
switch (node->opcode()) {
case IrOpcode::kBranch:
result = ReduceBranch(node);
break;
case IrOpcode::kIfTrue:
result = ReduceIfProjection(node, kTrue);
break;
case IrOpcode::kIfFalse:
result = ReduceIfProjection(node, kFalse);
break;
case IrOpcode::kLoop: // fallthrough
case IrOpcode::kMerge:
result = ReduceMerge(node);
break;
case IrOpcode::kEnd:
result = ReduceEnd(node);
break;
default:
break;
}
return result == node ? NoChange() : Replace(result);
}
// Try to statically fold a condition.
Decision DecideCondition(Node* cond) {
switch (cond->opcode()) {
case IrOpcode::kInt32Constant:
return Int32Matcher(cond).Is(0) ? kFalse : kTrue;
case IrOpcode::kInt64Constant:
return Int64Matcher(cond).Is(0) ? kFalse : kTrue;
case IrOpcode::kHeapConstant: {
Handle<HeapObject> object = HeapObjectMatcher(cond).Value().handle();
return object->BooleanValue() ? kTrue : kFalse;
}
default:
break;
}
return kUnknown;
}
// Reduce branches.
Node* ReduceBranch(Node* branch) {
if (DecideCondition(branch->InputAt(0)) != kUnknown) {
for (Node* use : branch->uses()) Revisit(use);
}
return branch;
}
// Reduce end by trimming away dead inputs.
Node* ReduceEnd(Node* node) {
// Count the number of live inputs.
int live = 0;
for (int index = 0; index < node->InputCount(); ++index) {
// Skip dead inputs.
if (node->InputAt(index)->opcode() == IrOpcode::kDeadControl) continue;
// Compact live inputs.
if (index != live) node->ReplaceInput(live, node->InputAt(index));
++live;
}
TRACE("ReduceEnd: #%d:%s (%d of %d live)\n", node->id(),
node->op()->mnemonic(), live, node->InputCount());
if (live == 0) return dead(); // No remaining inputs.
if (live < node->InputCount()) {
node->set_op(common()->End(live));
node->TrimInputCount(live);
}
return node;
}
// Reduce merges by trimming away dead inputs from the merge and phis.
Node* ReduceMerge(Node* node) {
// Count the number of live inputs.
int live = 0;
int index = 0;
int live_index = 0;
for (Node* const input : node->inputs()) {
if (input->opcode() != IrOpcode::kDeadControl) {
live++;
live_index = index;
}
index++;
}
TRACE("ReduceMerge: #%d:%s (%d of %d live)\n", node->id(),
node->op()->mnemonic(), live, index);
if (live == 0) return dead(); // no remaining inputs.
// Gather terminates, phis and effect phis to be edited.
NodeVector phis(zone_);
Node* terminate = nullptr;
for (Node* const use : node->uses()) {
if (NodeProperties::IsPhi(use)) {
phis.push_back(use);
} else if (use->opcode() == IrOpcode::kTerminate) {
DCHECK_NULL(terminate);
terminate = use;
}
}
if (live == 1) {
// All phis are redundant. Replace them with their live input.
for (Node* const phi : phis) {
Replace(phi, phi->InputAt(live_index));
}
// The terminate is not needed anymore.
if (terminate) Replace(terminate, dead());
// The merge itself is redundant.
return node->InputAt(live_index);
}
DCHECK_LE(2, live);
if (live < node->InputCount()) {
// Edit phis in place, removing dead inputs and revisiting them.
for (Node* const phi : phis) {
TRACE(" PhiInMerge: #%d:%s (%d live)\n", phi->id(),
phi->op()->mnemonic(), live);
RemoveDeadInputs(node, phi);
Revisit(phi);
}
// Edit the merge in place, removing dead inputs.
RemoveDeadInputs(node, node);
}
DCHECK_EQ(live, node->InputCount());
// Try to remove dead diamonds or introduce selects.
if (live == 2 && CheckPhisForSelect(phis)) {
DiamondMatcher matcher(node);
if (matcher.Matched() && matcher.IfProjectionsAreOwned()) {
// Dead diamond, i.e. neither the IfTrue nor the IfFalse nodes
// have uses except for the Merge. Remove the branch if there
// are no phis or replace phis with selects.
Node* control = NodeProperties::GetControlInput(matcher.Branch());
if (phis.size() == 0) {
// No phis. Remove the branch altogether.
TRACE(" DeadDiamond: #%d:Branch #%d:IfTrue #%d:IfFalse\n",
matcher.Branch()->id(), matcher.IfTrue()->id(),
matcher.IfFalse()->id());
return control;
} else {
// A small number of phis. Replace with selects.
Node* cond = matcher.Branch()->InputAt(0);
for (Node* phi : phis) {
Node* select = graph()->NewNode(
common()->Select(OpParameter<MachineType>(phi),
BranchHintOf(matcher.Branch()->op())),
cond, matcher.TrueInputOf(phi), matcher.FalseInputOf(phi));
TRACE(" MatchSelect: #%d:Branch #%d:IfTrue #%d:IfFalse -> #%d\n",
matcher.Branch()->id(), matcher.IfTrue()->id(),
matcher.IfFalse()->id(), select->id());
Replace(phi, select);
}
return control;
}
}
}
return node;
}
bool CheckPhisForSelect(const NodeVector& phis) {
if (phis.size() > static_cast<size_t>(max_phis_for_select_)) return false;
for (Node* phi : phis) {
if (phi->opcode() != IrOpcode::kPhi) return false; // no EffectPhis.
}
return true;
}
// Reduce if projections if the branch has a constant input.
Node* ReduceIfProjection(Node* node, Decision decision) {
Node* branch = node->InputAt(0);
DCHECK_EQ(IrOpcode::kBranch, branch->opcode());
Decision result = DecideCondition(branch->InputAt(0));
if (result == decision) {
// Fold a branch by replacing IfTrue/IfFalse with the branch control.
TRACE(" BranchReduce: #%d:%s => #%d:%s\n", branch->id(),
branch->op()->mnemonic(), node->id(), node->op()->mnemonic());
return branch->InputAt(1);
}
return result == kUnknown ? node : dead();
}
// Remove inputs to {node} corresponding to the dead inputs to {merge}
// and compact the remaining inputs, updating the operator.
void RemoveDeadInputs(Node* merge, Node* node) {
int live = 0;
for (int i = 0; i < merge->InputCount(); i++) {
// skip dead inputs.
if (merge->InputAt(i)->opcode() == IrOpcode::kDeadControl) continue;
// compact live inputs.
if (live != i) node->ReplaceInput(live, node->InputAt(i));
live++;
}
// compact remaining inputs.
int total = live;
for (int i = merge->InputCount(); i < node->InputCount(); i++) {
if (total != i) node->ReplaceInput(total, node->InputAt(i));
total++;
}
DCHECK_EQ(total, live + node->InputCount() - merge->InputCount());
DCHECK_NE(total, node->InputCount());
node->TrimInputCount(total);
node->set_op(common()->ResizeMergeOrPhi(node->op(), live));
}
};
void ControlReducer::ReduceGraph(Zone* zone, JSGraph* jsgraph,
int max_phis_for_select) {
GraphReducer graph_reducer(zone, jsgraph->graph());
CommonOperatorReducer common(&graph_reducer, jsgraph->graph(),
jsgraph->common(), jsgraph->machine());
ControlReducerImpl impl(&graph_reducer, zone, jsgraph);
impl.max_phis_for_select_ = max_phis_for_select;
graph_reducer.AddReducer(&impl);
graph_reducer.AddReducer(&common);
graph_reducer.ReduceGraph();
}
namespace {
class DummyEditor final : public AdvancedReducer::Editor {
public:
void Replace(Node* node, Node* replacement) final {
node->ReplaceUses(replacement);
}
void Revisit(Node* node) final {}
void ReplaceWithValue(Node* node, Node* value, Node* effect,
Node* control) final {}
};
} // namespace
Node* ControlReducer::ReduceMerge(JSGraph* jsgraph, Node* node,
int max_phis_for_select) {
Zone zone;
DummyEditor editor;
ControlReducerImpl impl(&editor, &zone, jsgraph);
impl.max_phis_for_select_ = max_phis_for_select;
return impl.ReduceMerge(node);
}
Node* ControlReducer::ReduceIfNodeForTesting(JSGraph* jsgraph, Node* node) {
Zone zone;
DummyEditor editor;
ControlReducerImpl impl(&editor, &zone, jsgraph);
switch (node->opcode()) {
case IrOpcode::kIfTrue:
return impl.ReduceIfProjection(node, kTrue);
case IrOpcode::kIfFalse:
return impl.ReduceIfProjection(node, kFalse);
default:
return node;
}
}
} // namespace compiler
} // namespace internal
} // namespace v8
......@@ -24,7 +24,7 @@ class JSCallReduction {
// constant callee being a well-known builtin with a BuiltinFunctionId.
bool HasBuiltinFunctionId() {
if (node_->opcode() != IrOpcode::kJSCallFunction) return false;
HeapObjectMatcher<Object> m(NodeProperties::GetValueInput(node_, 0));
HeapObjectMatcher m(NodeProperties::GetValueInput(node_, 0));
if (!m.HasValue() || !m.Value().handle()->IsJSFunction()) return false;
Handle<JSFunction> function = Handle<JSFunction>::cast(m.Value().handle());
return function->shared()->HasBuiltinFunctionId();
......@@ -33,7 +33,7 @@ class JSCallReduction {
// Retrieves the BuiltinFunctionId as described above.
BuiltinFunctionId GetBuiltinFunctionId() {
DCHECK_EQ(IrOpcode::kJSCallFunction, node_->opcode());
HeapObjectMatcher<Object> m(NodeProperties::GetValueInput(node_, 0));
HeapObjectMatcher m(NodeProperties::GetValueInput(node_, 0));
Handle<JSFunction> function = Handle<JSFunction>::cast(m.Value().handle());
return function->shared()->builtin_function_id();
}
......
......@@ -5,9 +5,11 @@
#include "src/compiler/js-context-specialization.h"
#include "src/compiler/common-operator.h"
#include "src/compiler/js-graph.h"
#include "src/compiler/js-operator.h"
#include "src/compiler/node-matchers.h"
#include "src/compiler/node-properties.h"
#include "src/contexts.h"
namespace v8 {
namespace internal {
......@@ -27,7 +29,7 @@ Reduction JSContextSpecializer::Reduce(Node* node) {
Reduction JSContextSpecializer::ReduceJSLoadContext(Node* node) {
DCHECK_EQ(IrOpcode::kJSLoadContext, node->opcode());
HeapObjectMatcher<Context> m(NodeProperties::GetValueInput(node, 0));
HeapObjectMatcher m(NodeProperties::GetValueInput(node, 0));
// If the context is not constant, no reduction can occur.
if (!m.HasValue()) {
return NoChange();
......@@ -36,9 +38,9 @@ Reduction JSContextSpecializer::ReduceJSLoadContext(Node* node) {
const ContextAccess& access = ContextAccessOf(node->op());
// Find the right parent context.
Context* context = *m.Value().handle();
Handle<Context> context = Handle<Context>::cast(m.Value().handle());
for (size_t i = access.depth(); i > 0; --i) {
context = context->previous();
context = handle(context->previous(), isolate());
}
// If the access itself is mutable, only fold-in the parent.
......@@ -50,13 +52,11 @@ Reduction JSContextSpecializer::ReduceJSLoadContext(Node* node) {
const Operator* op = jsgraph_->javascript()->LoadContext(
0, access.index(), access.immutable());
node->set_op(op);
Handle<Object> context_handle =
Handle<Object>(context, jsgraph_->isolate());
node->ReplaceInput(0, jsgraph_->Constant(context_handle));
node->ReplaceInput(0, jsgraph_->Constant(context));
return Changed(node);
}
Handle<Object> value = Handle<Object>(
context->get(static_cast<int>(access.index())), jsgraph_->isolate());
Handle<Object> value =
handle(context->get(static_cast<int>(access.index())), isolate());
// Even though the context slot is immutable, the context might have escaped
// before the function to which it belongs has initialized the slot.
......@@ -78,7 +78,7 @@ Reduction JSContextSpecializer::ReduceJSLoadContext(Node* node) {
Reduction JSContextSpecializer::ReduceJSStoreContext(Node* node) {
DCHECK_EQ(IrOpcode::kJSStoreContext, node->opcode());
HeapObjectMatcher<Context> m(NodeProperties::GetValueInput(node, 0));
HeapObjectMatcher m(NodeProperties::GetValueInput(node, 0));
// If the context is not constant, no reduction can occur.
if (!m.HasValue()) {
return NoChange();
......@@ -92,20 +92,24 @@ Reduction JSContextSpecializer::ReduceJSStoreContext(Node* node) {
}
// Find the right parent context.
Context* context = *m.Value().handle();
Handle<Context> context = Handle<Context>::cast(m.Value().handle());
for (size_t i = access.depth(); i > 0; --i) {
context = context->previous();
context = handle(context->previous(), isolate());
}
const Operator* op = jsgraph_->javascript()->StoreContext(0, access.index());
node->set_op(op);
Handle<Object> new_context_handle =
Handle<Object>(context, jsgraph_->isolate());
node->ReplaceInput(0, jsgraph_->Constant(new_context_handle));
node->set_op(javascript()->StoreContext(0, access.index()));
node->ReplaceInput(0, jsgraph_->Constant(context));
return Changed(node);
}
Isolate* JSContextSpecializer::isolate() const { return jsgraph()->isolate(); }
JSOperatorBuilder* JSContextSpecializer::javascript() const {
return jsgraph()->javascript();
}
} // namespace compiler
} // namespace internal
} // namespace v8
......@@ -6,13 +6,16 @@
#define V8_COMPILER_JS_CONTEXT_SPECIALIZATION_H_
#include "src/compiler/graph-reducer.h"
#include "src/compiler/js-graph.h"
#include "src/contexts.h"
namespace v8 {
namespace internal {
namespace compiler {
// Forward declarations.
class JSGraph;
class JSOperatorBuilder;
// Specializes a given JSGraph to a given context, potentially constant folding
// some {LoadContext} nodes or strength reducing some {StoreContext} nodes.
class JSContextSpecializer : public AdvancedReducer {
......@@ -27,10 +30,17 @@ class JSContextSpecializer : public AdvancedReducer {
Reduction ReduceJSStoreContext(Node* node);
private:
JSGraph* jsgraph_;
Isolate* isolate() const;
JSOperatorBuilder* javascript() const;
JSGraph* jsgraph() const { return jsgraph_; }
JSGraph* const jsgraph_;
DISALLOW_COPY_AND_ASSIGN(JSContextSpecializer);
};
}
}
} // namespace v8::internal::compiler
} // namespace compiler
} // namespace internal
} // namespace v8
#endif // V8_COMPILER_JS_CONTEXT_SPECIALIZATION_H_
......@@ -238,11 +238,12 @@ Reduction JSInliner::Reduce(Node* node) {
if (node->opcode() != IrOpcode::kJSCallFunction) return NoChange();
JSCallFunctionAccessor call(node);
HeapObjectMatcher<JSFunction> match(call.jsfunction());
HeapObjectMatcher match(call.jsfunction());
if (!match.HasValue()) return NoChange();
Handle<JSFunction> function = match.Value().handle();
if (!function->IsJSFunction()) return NoChange();
if (!match.Value().handle()->IsJSFunction()) return NoChange();
Handle<JSFunction> function =
Handle<JSFunction>::cast(match.Value().handle());
if (mode_ == kRestrictedInlining && !function->shared()->force_inline()) {
return NoChange();
}
......
......@@ -179,11 +179,12 @@ Reduction JSIntrinsicLowering::ReduceHeapObjectGetMap(Node* node) {
Reduction JSIntrinsicLowering::ReduceIncrementStatsCounter(Node* node) {
if (!FLAG_native_code_counters) return ChangeToUndefined(node);
HeapObjectMatcher<String> m(NodeProperties::GetValueInput(node, 0));
HeapObjectMatcher m(NodeProperties::GetValueInput(node, 0));
if (!m.HasValue() || !m.Value().handle()->IsString()) {
return ChangeToUndefined(node);
}
SmartArrayPointer<char> name = m.Value().handle()->ToCString();
SmartArrayPointer<char> name =
Handle<String>::cast(m.Value().handle())->ToCString();
StatsCounter counter(jsgraph()->isolate(), name.get());
if (!counter.Enabled()) return ChangeToUndefined(node);
......
......@@ -824,7 +824,7 @@ Reduction JSTypedLowering::ReduceJSLoadProperty(Node* node) {
Node* key = NodeProperties::GetValueInput(node, 1);
Node* base = NodeProperties::GetValueInput(node, 0);
Type* key_type = NodeProperties::GetBounds(key).upper;
HeapObjectMatcher<Object> mbase(base);
HeapObjectMatcher mbase(base);
if (mbase.HasValue() && mbase.Value().handle()->IsJSTypedArray()) {
Handle<JSTypedArray> const array =
Handle<JSTypedArray>::cast(mbase.Value().handle());
......@@ -871,7 +871,7 @@ Reduction JSTypedLowering::ReduceJSStoreProperty(Node* node) {
Node* value = NodeProperties::GetValueInput(node, 2);
Type* key_type = NodeProperties::GetBounds(key).upper;
Type* value_type = NodeProperties::GetBounds(value).upper;
HeapObjectMatcher<Object> mbase(base);
HeapObjectMatcher mbase(base);
if (mbase.HasValue() && mbase.Value().handle()->IsJSTypedArray()) {
Handle<JSTypedArray> const array =
Handle<JSTypedArray>::cast(mbase.Value().handle());
......@@ -1132,8 +1132,8 @@ Reduction JSTypedLowering::ReduceJSCreateClosure(Node* node) {
Reduction JSTypedLowering::ReduceJSCreateLiteralArray(Node* node) {
DCHECK_EQ(IrOpcode::kJSCreateLiteralArray, node->opcode());
HeapObjectMatcher<FixedArray> mconst(NodeProperties::GetValueInput(node, 2));
int length = mconst.Value().handle()->length();
HeapObjectMatcher mconst(NodeProperties::GetValueInput(node, 2));
int length = Handle<FixedArray>::cast(mconst.Value().handle())->length();
int flags = OpParameter<int>(node->op());
// Use the FastCloneShallowArrayStub only for shallow boilerplates up to the
......@@ -1162,9 +1162,9 @@ Reduction JSTypedLowering::ReduceJSCreateLiteralArray(Node* node) {
Reduction JSTypedLowering::ReduceJSCreateLiteralObject(Node* node) {
DCHECK_EQ(IrOpcode::kJSCreateLiteralObject, node->opcode());
HeapObjectMatcher<FixedArray> mconst(NodeProperties::GetValueInput(node, 2));
HeapObjectMatcher mconst(NodeProperties::GetValueInput(node, 2));
// Constants are pairs, see ObjectLiteral::properties_count().
int length = mconst.Value().handle()->length() / 2;
int length = Handle<FixedArray>::cast(mconst.Value().handle())->length() / 2;
int flags = OpParameter<int>(node->op());
// Use the FastCloneShallowObjectStub only for shallow boilerplates without
......@@ -1227,9 +1227,10 @@ Reduction JSTypedLowering::ReduceJSCreateWithContext(Node* node) {
Reduction JSTypedLowering::ReduceJSCreateBlockContext(Node* node) {
DCHECK_EQ(IrOpcode::kJSCreateBlockContext, node->opcode());
Node* const input = NodeProperties::GetValueInput(node, 0);
HeapObjectMatcher<ScopeInfo> minput(input);
HeapObjectMatcher minput(input);
DCHECK(minput.HasValue()); // TODO(mstarzinger): Make ScopeInfo static.
int context_length = minput.Value().handle()->ContextLength();
int context_length =
Handle<ScopeInfo>::cast(minput.Value().handle())->ContextLength();
if (FLAG_turbo_allocate && context_length < kBlockContextAllocationLimit) {
// JSCreateBlockContext(s:scope[length < limit], f)
Node* const effect = NodeProperties::GetEffectInput(node);
......
......@@ -152,11 +152,10 @@ typedef FloatMatcher<double, IrOpcode::kNumberConstant> NumberMatcher;
// A pattern matcher for heap object constants.
template <typename T>
struct HeapObjectMatcher final
: public ValueMatcher<Unique<T>, IrOpcode::kHeapConstant> {
: public ValueMatcher<Unique<HeapObject>, IrOpcode::kHeapConstant> {
explicit HeapObjectMatcher(Node* node)
: ValueMatcher<Unique<T>, IrOpcode::kHeapConstant>(node) {}
: ValueMatcher<Unique<HeapObject>, IrOpcode::kHeapConstant>(node) {}
};
......
......@@ -3,6 +3,7 @@
// found in the LICENSE file.
#include "src/compiler/js-context-specialization.h"
#include "src/compiler/js-graph.h"
#include "src/compiler/js-operator.h"
#include "src/compiler/node-matchers.h"
#include "src/compiler/node-properties.h"
......@@ -91,7 +92,7 @@ TEST(ReduceJSLoadContext) {
CHECK(r.Changed());
Node* new_context_input = NodeProperties::GetValueInput(r.replacement(), 0);
CHECK_EQ(IrOpcode::kHeapConstant, new_context_input->opcode());
HeapObjectMatcher<Context> match(new_context_input);
HeapObjectMatcher match(new_context_input);
CHECK_EQ(*native, *match.Value().handle());
ContextAccess access = OpParameter<ContextAccess>(r.replacement());
CHECK_EQ(Context::GLOBAL_EVAL_FUN_INDEX, static_cast<int>(access.index()));
......@@ -107,7 +108,7 @@ TEST(ReduceJSLoadContext) {
CHECK(r.Changed());
CHECK(r.replacement() != load);
HeapObjectMatcher<Object> match(r.replacement());
HeapObjectMatcher match(r.replacement());
CHECK(match.HasValue());
CHECK_EQ(*expected, *match.Value().handle());
}
......@@ -170,7 +171,7 @@ TEST(ReduceJSStoreContext) {
CHECK(r.Changed());
Node* new_context_input = NodeProperties::GetValueInput(r.replacement(), 0);
CHECK_EQ(IrOpcode::kHeapConstant, new_context_input->opcode());
HeapObjectMatcher<Context> match(new_context_input);
HeapObjectMatcher match(new_context_input);
CHECK_EQ(*native, *match.Value().handle());
ContextAccess access = OpParameter<ContextAccess>(r.replacement());
CHECK_EQ(Context::GLOBAL_EVAL_FUN_INDEX, static_cast<int>(access.index()));
......@@ -245,7 +246,7 @@ TEST(SpecializeToContext) {
CHECK_EQ(other_load, other_use->InputAt(0));
Node* replacement = value_use->InputAt(0);
HeapObjectMatcher<Object> match(replacement);
HeapObjectMatcher match(replacement);
CHECK(match.HasValue());
CHECK_EQ(*expected, *match.Value().handle());
}
......
......@@ -69,7 +69,7 @@ class RepresentationChangerTester : public HandleAndZoneScope,
}
void CheckHeapConstant(Node* n, HeapObject* expected) {
HeapObjectMatcher<HeapObject> m(n);
HeapObjectMatcher m(n);
CHECK(m.HasValue());
CHECK_EQ(expected, *m.Value().handle());
}
......
......@@ -275,7 +275,7 @@ TEST_F(JSTypeFeedbackTest, JSLoadNamedGlobalPropertyCellSmiWithDeoptimization) {
access, CaptureEq(&cell_capture), graph()->start(), graph()->start());
EXPECT_THAT(r.replacement(), load_field_match);
HeapObjectMatcher<PropertyCell> cell(cell_capture.value());
HeapObjectMatcher cell(cell_capture.value());
EXPECT_TRUE(cell.HasValue());
EXPECT_TRUE(cell.Value().handle()->IsPropertyCell());
......@@ -327,7 +327,7 @@ TEST_F(JSTypeFeedbackTest,
access, CaptureEq(&cell_capture), graph()->start(), graph()->start());
EXPECT_THAT(r.replacement(), load_field_match);
HeapObjectMatcher<PropertyCell> cell(cell_capture.value());
HeapObjectMatcher cell(cell_capture.value());
EXPECT_TRUE(cell.HasValue());
EXPECT_TRUE(cell.Value().handle()->IsPropertyCell());
......
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