Revision: 24172
Author: [email protected]
Date: Wed Sep 24 09:28:56 2014 UTC
Log: [turbofan] Add length operand to LoadElement and StoreElement.
This is preliminary work, required to properly support bounds checking for
typed array loads/stores.
TEST=compiler-unittests,cctest
[email protected]
Review URL: https://codereview.chromium.org/602563002
https://code.google.com/p/v8/source/detail?r=24172
Modified:
/branches/bleeding_edge/src/compiler/generic-node-inl.h
/branches/bleeding_edge/src/compiler/generic-node.h
/branches/bleeding_edge/src/compiler/js-generic-lowering.cc
/branches/bleeding_edge/src/compiler/js-typed-lowering.cc
/branches/bleeding_edge/src/compiler/simplified-lowering.cc
/branches/bleeding_edge/src/compiler/simplified-operator-unittest.cc
/branches/bleeding_edge/src/compiler/simplified-operator.cc
/branches/bleeding_edge/src/compiler/simplified-operator.h
/branches/bleeding_edge/test/cctest/compiler/simplified-graph-builder.h
/branches/bleeding_edge/test/cctest/compiler/test-node.cc
/branches/bleeding_edge/test/cctest/compiler/test-simplified-lowering.cc
=======================================
--- /branches/bleeding_edge/src/compiler/generic-node-inl.h Fri Aug 29
12:14:52 2014 UTC
+++ /branches/bleeding_edge/src/compiler/generic-node-inl.h Wed Sep 24
09:28:56 2014 UTC
@@ -176,6 +176,16 @@
}
ReplaceInput(index, to_insert);
}
+
+template <class B, class S>
+void GenericNode<B, S>::RemoveInput(int index) {
+ DCHECK(index >= 0 && index < InputCount());
+ // TODO(turbofan): Optimize this implementation!
+ for (; index < InputCount() - 1; ++index) {
+ ReplaceInput(index, InputAt(index + 1));
+ }
+ TrimInputCount(InputCount() - 1);
+}
template <class B, class S>
void GenericNode<B, S>::AppendUse(Use* use) {
=======================================
--- /branches/bleeding_edge/src/compiler/generic-node.h Tue Aug 26 13:09:08
2014 UTC
+++ /branches/bleeding_edge/src/compiler/generic-node.h Wed Sep 24 09:28:56
2014 UTC
@@ -41,6 +41,7 @@
inline void ReplaceInput(int index, GenericNode* new_input);
inline void AppendInput(Zone* zone, GenericNode* new_input);
inline void InsertInput(Zone* zone, int index, GenericNode* new_input);
+ inline void RemoveInput(int index);
int UseCount() { return use_count_; }
S* UseAt(int index) {
@@ -56,7 +57,7 @@
inline void ReplaceUsesIf(UnaryPredicate pred, GenericNode* replace_to);
inline void RemoveAllInputs();
- void TrimInputCount(int input_count);
+ inline void TrimInputCount(int input_count);
class Inputs {
public:
=======================================
--- /branches/bleeding_edge/src/compiler/js-generic-lowering.cc Fri Sep 12
14:49:07 2014 UTC
+++ /branches/bleeding_edge/src/compiler/js-generic-lowering.cc Wed Sep 24
09:28:56 2014 UTC
@@ -176,14 +176,7 @@
if (has_frame_state) {
// Remove the frame state from inputs.
- // TODO(jarin) This should use Node::RemoveInput (which does not exist
yet).
- int dest = NodeProperties::FirstFrameStateIndex(node);
- for (int i = NodeProperties::PastFrameStateIndex(node);
- i < node->InputCount(); i++) {
- node->ReplaceInput(dest, node->InputAt(i));
- dest++;
- }
- node->TrimInputCount(dest);
+ node->RemoveInput(NodeProperties::FirstFrameStateIndex(node));
}
ReplaceWithRuntimeCall(node, Runtime::kBooleanize);
=======================================
--- /branches/bleeding_edge/src/compiler/js-typed-lowering.cc Mon Sep 22
07:17:13 2014 UTC
+++ /branches/bleeding_edge/src/compiler/js-typed-lowering.cc Wed Sep 24
09:28:56 2014 UTC
@@ -540,6 +540,8 @@
JSTypedArray* array =
JSTypedArray::cast(*base_type->AsConstant()->Value());
ElementsKind elements_kind = array->map()->elements_kind();
ExternalArrayType type = array->type();
+ uint32_t length;
+ CHECK(array->length()->ToUint32(&length));
ElementAccess element_access;
Node* elements = graph()->NewNode(
simplified()->LoadField(AccessBuilder::ForJSObjectElements()),
base,
@@ -555,7 +557,8 @@
}
Node* value =
graph()->NewNode(simplified()->LoadElement(element_access),
elements,
- key, NodeProperties::GetEffectInput(node));
+ key, jsgraph()->Uint32Constant(length),
+ NodeProperties::GetEffectInput(node));
return ReplaceEagerly(node, value);
}
return NoChange();
@@ -599,9 +602,10 @@
NodeProperties::GetControlInput(node));
Node* if_true = graph()->NewNode(common()->IfTrue(), branch);
- Node* store = graph()->NewNode(
- simplified()->StoreElement(element_access), elements, key, value,
- NodeProperties::GetEffectInput(node), if_true);
+ Node* store =
+ graph()->NewNode(simplified()->StoreElement(element_access),
elements,
+ key, jsgraph()->Uint32Constant(length), value,
+ NodeProperties::GetEffectInput(node), if_true);
Node* if_false = graph()->NewNode(common()->IfFalse(), branch);
=======================================
--- /branches/bleeding_edge/src/compiler/simplified-lowering.cc Fri Sep 19
09:56:12 2014 UTC
+++ /branches/bleeding_edge/src/compiler/simplified-lowering.cc Wed Sep 24
09:28:56 2014 UTC
@@ -596,7 +596,8 @@
ElementAccess access = ElementAccessOf(node->op());
ProcessInput(node, 0, changer_->TypeForBasePointer(access));
ProcessInput(node, 1, kMachInt32); // element index
- ProcessRemainingInputs(node, 2);
+ ProcessInput(node, 2, kMachInt32); // length
+ ProcessRemainingInputs(node, 3);
SetOutput(node, AssumeImplicitFloat32Change(access.machine_type));
if (lower()) lowering->DoLoadElement(node);
break;
@@ -605,8 +606,9 @@
ElementAccess access = ElementAccessOf(node->op());
ProcessInput(node, 0, changer_->TypeForBasePointer(access));
ProcessInput(node, 1, kMachInt32); // element index
- ProcessInput(node, 2,
AssumeImplicitFloat32Change(access.machine_type));
- ProcessRemainingInputs(node, 3);
+ ProcessInput(node, 2, kMachInt32); // length
+ ProcessInput(node, 3,
AssumeImplicitFloat32Change(access.machine_type));
+ ProcessRemainingInputs(node, 4);
SetOutput(node, 0);
if (lower()) lowering->DoStoreElement(node);
break;
@@ -867,6 +869,7 @@
const ElementAccess& access = ElementAccessOf(node->op());
node->set_op(machine()->Load(access.machine_type));
node->ReplaceInput(1, ComputeIndex(access, node->InputAt(1)));
+ node->RemoveInput(2);
}
@@ -877,6 +880,7 @@
node->set_op(
machine()->Store(StoreRepresentation(access.machine_type, kind)));
node->ReplaceInput(1, ComputeIndex(access, node->InputAt(1)));
+ node->RemoveInput(2);
}
=======================================
--- /branches/bleeding_edge/src/compiler/simplified-operator-unittest.cc
Mon Sep 15 09:09:45 2014 UTC
+++ /branches/bleeding_edge/src/compiler/simplified-operator-unittest.cc
Wed Sep 24 09:28:56 2014 UTC
@@ -11,6 +11,14 @@
namespace internal {
namespace compiler {
+// TODO(bmeurer): Drop once we use std::ostream instead of our OStream.
+inline std::ostream& operator<<(std::ostream& os, const ElementAccess&
access) {
+ OStringStream ost;
+ ost << access;
+ return os << ost.c_str();
+}
+
+
//
-----------------------------------------------------------------------------
// Pure operators.
@@ -112,6 +120,103 @@
INSTANTIATE_TEST_CASE_P(SimplifiedOperatorTest, SimplifiedPureOperatorTest,
::testing::ValuesIn(kPureOperators));
+
+//
-----------------------------------------------------------------------------
+// Element access operators.
+
+namespace {
+
+const ElementAccess kElementAccesses[] = {
+ {kTaggedBase, FixedArray::kHeaderSize, Type::Any(), kMachAnyTagged},
+ {kUntaggedBase, kNonHeapObjectHeaderSize - kHeapObjectTag, Type::Any(),
+ kMachInt8},
+ {kUntaggedBase, kNonHeapObjectHeaderSize - kHeapObjectTag, Type::Any(),
+ kMachInt16},
+ {kUntaggedBase, kNonHeapObjectHeaderSize - kHeapObjectTag, Type::Any(),
+ kMachInt32},
+ {kUntaggedBase, kNonHeapObjectHeaderSize - kHeapObjectTag, Type::Any(),
+ kMachUint8},
+ {kUntaggedBase, kNonHeapObjectHeaderSize - kHeapObjectTag, Type::Any(),
+ kMachUint16},
+ {kUntaggedBase, kNonHeapObjectHeaderSize - kHeapObjectTag, Type::Any(),
+ kMachUint32},
+ {kUntaggedBase, 0, Type::Signed32(), kMachInt8},
+ {kUntaggedBase, 0, Type::Unsigned32(), kMachUint8},
+ {kUntaggedBase, 0, Type::Signed32(), kMachInt16},
+ {kUntaggedBase, 0, Type::Unsigned32(), kMachUint16},
+ {kUntaggedBase, 0, Type::Signed32(), kMachInt32},
+ {kUntaggedBase, 0, Type::Unsigned32(), kMachUint32},
+ {kUntaggedBase, 0, Type::Number(), kRepFloat32},
+ {kUntaggedBase, 0, Type::Number(), kRepFloat64},
+ {kTaggedBase, FixedTypedArrayBase::kDataOffset, Type::Signed32(),
+ kMachInt8},
+ {kTaggedBase, FixedTypedArrayBase::kDataOffset, Type::Unsigned32(),
+ kMachUint8},
+ {kTaggedBase, FixedTypedArrayBase::kDataOffset, Type::Signed32(),
+ kMachInt16},
+ {kTaggedBase, FixedTypedArrayBase::kDataOffset, Type::Unsigned32(),
+ kMachUint16},
+ {kTaggedBase, FixedTypedArrayBase::kDataOffset, Type::Signed32(),
+ kMachInt32},
+ {kTaggedBase, FixedTypedArrayBase::kDataOffset, Type::Unsigned32(),
+ kMachUint32},
+ {kTaggedBase, FixedTypedArrayBase::kDataOffset, Type::Number(),
+ kRepFloat32},
+ {kTaggedBase, FixedTypedArrayBase::kDataOffset, Type::Number(),
+ kRepFloat64}};
+
+} // namespace
+
+
+class SimplifiedElementAccessOperatorTest
+ : public TestWithZone,
+ public ::testing::WithParamInterface<ElementAccess> {};
+
+
+TEST_P(SimplifiedElementAccessOperatorTest, LoadElement) {
+ SimplifiedOperatorBuilder simplified(zone());
+ const ElementAccess& access = GetParam();
+ const Operator* op = simplified.LoadElement(access);
+
+ EXPECT_EQ(IrOpcode::kLoadElement, op->opcode());
+ EXPECT_EQ(Operator::kNoThrow | Operator::kNoWrite, op->properties());
+ EXPECT_EQ(access, ElementAccessOf(op));
+
+ EXPECT_EQ(3, OperatorProperties::GetValueInputCount(op));
+ EXPECT_EQ(1, OperatorProperties::GetEffectInputCount(op));
+ EXPECT_EQ(0, OperatorProperties::GetControlInputCount(op));
+ EXPECT_EQ(4, OperatorProperties::GetTotalInputCount(op));
+
+ EXPECT_EQ(1, OperatorProperties::GetValueOutputCount(op));
+ EXPECT_EQ(1, OperatorProperties::GetEffectOutputCount(op));
+ EXPECT_EQ(0, OperatorProperties::GetControlOutputCount(op));
+}
+
+
+TEST_P(SimplifiedElementAccessOperatorTest, StoreElement) {
+ SimplifiedOperatorBuilder simplified(zone());
+ const ElementAccess& access = GetParam();
+ const Operator* op = simplified.StoreElement(access);
+
+ EXPECT_EQ(IrOpcode::kStoreElement, op->opcode());
+ EXPECT_EQ(Operator::kNoRead | Operator::kNoThrow, op->properties());
+ EXPECT_EQ(access, ElementAccessOf(op));
+
+ EXPECT_EQ(4, OperatorProperties::GetValueInputCount(op));
+ EXPECT_EQ(1, OperatorProperties::GetEffectInputCount(op));
+ EXPECT_EQ(1, OperatorProperties::GetControlInputCount(op));
+ EXPECT_EQ(6, OperatorProperties::GetTotalInputCount(op));
+
+ EXPECT_EQ(0, OperatorProperties::GetValueOutputCount(op));
+ EXPECT_EQ(1, OperatorProperties::GetEffectOutputCount(op));
+ EXPECT_EQ(0, OperatorProperties::GetControlOutputCount(op));
+}
+
+
+INSTANTIATE_TEST_CASE_P(SimplifiedOperatorTest,
+ SimplifiedElementAccessOperatorTest,
+ ::testing::ValuesIn(kElementAccesses));
+
} // namespace compiler
} // namespace internal
} // namespace v8
=======================================
--- /branches/bleeding_edge/src/compiler/simplified-operator.cc Wed Sep 17
14:47:25 2014 UTC
+++ /branches/bleeding_edge/src/compiler/simplified-operator.cc Wed Sep 24
09:28:56 2014 UTC
@@ -13,6 +13,38 @@
namespace internal {
namespace compiler {
+OStream& operator<<(OStream& os, BaseTaggedness base_taggedness) {
+ switch (base_taggedness) {
+ case kUntaggedBase:
+ return os << "untagged base";
+ case kTaggedBase:
+ return os << "tagged base";
+ }
+ UNREACHABLE();
+ return os;
+}
+
+
+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.machine_type == rhs.machine_type;
+}
+
+
+bool operator!=(ElementAccess const& lhs, ElementAccess const& rhs) {
+ return !(lhs == rhs);
+}
+
+
+OStream& operator<<(OStream& os, ElementAccess const& access) {
+ os << "[" << access.base_is_tagged << ", " << access.header_size << ", ";
+ access.type->PrintTo(os);
+ os << ", " << access.machine_type << "]";
+ return os;
+}
+
+
const FieldAccess& FieldAccessOf(const Operator* op) {
DCHECK_NOT_NULL(op);
DCHECK(op->opcode() == IrOpcode::kLoadField ||
@@ -49,11 +81,11 @@
// Specialization for static parameters of type {ElementAccess}.
template <>
struct StaticParameterTraits<ElementAccess> {
- static OStream& PrintTo(OStream& os, const ElementAccess& val) {
- return os << val.header_size;
+ static OStream& PrintTo(OStream& os, const ElementAccess& access) {
+ return os << access;
}
- static int HashCode(const ElementAccess& val) {
- return (val.header_size < 16) | (val.machine_type & 0xffff);
+ 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 &&
@@ -93,8 +125,8 @@
#define ACCESS_OP_LIST(V) \
V(LoadField, FieldAccess, Operator::kNoWrite, 1, 1) \
V(StoreField, FieldAccess, Operator::kNoRead, 2, 0) \
- V(LoadElement, ElementAccess, Operator::kNoWrite, 2, 1) \
- V(StoreElement, ElementAccess, Operator::kNoRead, 3, 0)
+ V(LoadElement, ElementAccess, Operator::kNoWrite, 3, 1) \
+ V(StoreElement, ElementAccess, Operator::kNoRead, 4, 0)
struct SimplifiedOperatorBuilderImpl FINAL {
=======================================
--- /branches/bleeding_edge/src/compiler/simplified-operator.h Wed Sep 17
14:47:25 2014 UTC
+++ /branches/bleeding_edge/src/compiler/simplified-operator.h Wed Sep 24
09:28:56 2014 UTC
@@ -28,6 +28,8 @@
enum BaseTaggedness { kUntaggedBase, kTaggedBase };
+OStream& operator<<(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.
@@ -55,6 +57,11 @@
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);
+
+OStream& operator<<(OStream&, ElementAccess const&);
+
// If the accessed object is not a heap object, add this to the
header_size.
static const int kNonHeapObjectHeaderSize = kHeapObjectTag;
@@ -122,8 +129,12 @@
const Operator* LoadField(const FieldAccess&);
const Operator* StoreField(const FieldAccess&);
- const Operator* LoadElement(const ElementAccess&);
- const Operator* StoreElement(const ElementAccess&);
+
+ // load-element [base + index], length
+ const Operator* LoadElement(ElementAccess const&);
+
+ // store-element [base + index], length, value
+ const Operator* StoreElement(ElementAccess const&);
private:
Zone* zone() const { return zone_; }
=======================================
--- /branches/bleeding_edge/test/cctest/compiler/simplified-graph-builder.h
Wed Sep 10 12:23:45 2014 UTC
+++ /branches/bleeding_edge/test/cctest/compiler/simplified-graph-builder.h
Wed Sep 24 09:28:56 2014 UTC
@@ -127,12 +127,14 @@
Node* StoreField(const FieldAccess& access, Node* object, Node* value) {
return NewNode(simplified()->StoreField(access), object, value);
}
- Node* LoadElement(const ElementAccess& access, Node* object, Node*
index) {
- return NewNode(simplified()->LoadElement(access), object, index);
+ Node* LoadElement(const ElementAccess& access, Node* object, Node* index,
+ Node* length) {
+ return NewNode(simplified()->LoadElement(access), object, index,
length);
}
Node* StoreElement(const ElementAccess& access, Node* object, Node*
index,
- Node* value) {
- return NewNode(simplified()->StoreElement(access), object, index,
value);
+ Node* length, Node* value) {
+ return NewNode(simplified()->StoreElement(access), object, index,
length,
+ value);
}
protected:
=======================================
--- /branches/bleeding_edge/test/cctest/compiler/test-node.cc Fri Aug 29
12:14:52 2014 UTC
+++ /branches/bleeding_edge/test/cctest/compiler/test-node.cc Wed Sep 24
09:28:56 2014 UTC
@@ -336,6 +336,27 @@
++current;
CHECK(current == uses.end());
}
+
+
+TEST(RemoveInput) {
+ GraphTester graph;
+
+ Node* n0 = graph.NewNode(&dummy_operator);
+ Node* n1 = graph.NewNode(&dummy_operator, n0);
+ Node* n2 = graph.NewNode(&dummy_operator, n0, n1);
+
+ n1->RemoveInput(0);
+ CHECK_EQ(0, n1->InputCount());
+ CHECK_EQ(1, n0->UseCount());
+
+ n2->RemoveInput(0);
+ CHECK_EQ(1, n2->InputCount());
+ CHECK_EQ(0, n0->UseCount());
+ CHECK_EQ(1, n1->UseCount());
+
+ n2->RemoveInput(0);
+ CHECK_EQ(0, n2->InputCount());
+}
TEST(AppendInputsAndIterator) {
=======================================
---
/branches/bleeding_edge/test/cctest/compiler/test-simplified-lowering.cc
Fri Sep 19 09:56:12 2014 UTC
+++
/branches/bleeding_edge/test/cctest/compiler/test-simplified-lowering.cc
Wed Sep 24 09:28:56 2014 UTC
@@ -207,8 +207,10 @@
TEST(RunLoadStoreFixedArrayIndex) {
SimplifiedLoweringTester<Object*> t(kMachAnyTagged);
ElementAccess access = AccessBuilder::ForFixedArrayElement();
- Node* load = t.LoadElement(access, t.Parameter(0), t.Int32Constant(0));
- t.StoreElement(access, t.Parameter(0), t.Int32Constant(1), load);
+ Node* load = t.LoadElement(access, t.Parameter(0), t.Int32Constant(0),
+ t.Int32Constant(2));
+ t.StoreElement(access, t.Parameter(0), t.Int32Constant(1),
t.Int32Constant(2),
+ load);
t.Return(load);
t.LowerAllNodes();
@@ -231,14 +233,16 @@
TEST(RunLoadStoreArrayBuffer) {
SimplifiedLoweringTester<Object*> t(kMachAnyTagged);
const int index = 12;
+ const int array_length = 2 * index;
ElementAccess buffer_access =
AccessBuilder::ForBackingStoreElement(kMachInt8);
Node* backing_store = t.LoadField(
AccessBuilder::ForJSArrayBufferBackingStore(), t.Parameter(0));
Node* load =
- t.LoadElement(buffer_access, backing_store, t.Int32Constant(index));
+ t.LoadElement(buffer_access, backing_store, t.Int32Constant(index),
+ t.Int32Constant(array_length));
t.StoreElement(buffer_access, backing_store, t.Int32Constant(index + 1),
- load);
+ t.Int32Constant(array_length), load);
t.Return(t.jsgraph.TrueConstant());
t.LowerAllNodes();
@@ -246,7 +250,6 @@
if (Pipeline::SupportedTarget()) {
Handle<JSArrayBuffer> array = t.factory()->NewJSArrayBuffer();
- const int array_length = 2 * index;
Runtime::SetupArrayBufferAllocatingData(t.isolate(), array,
array_length);
uint8_t* data = reinterpret_cast<uint8_t*>(array->backing_store());
for (int i = 0; i < array_length; i++) {
@@ -326,8 +329,9 @@
kMachAnyTagged};
SimplifiedLoweringTester<Object*> t;
- Node* load = t.LoadElement(access, t.PointerConstant(smis),
- t.Int32Constant(static_cast<int>(j)));
+ Node* load = t.LoadElement(
+ access, t.PointerConstant(smis),
t.Int32Constant(static_cast<int>(j)),
+ t.Int32Constant(static_cast<int>(arraysize(smis))));
t.Return(load);
t.LowerAllNodes();
@@ -356,7 +360,8 @@
SimplifiedLoweringTester<Object*> t(kMachAnyTagged);
Node* p0 = t.Parameter(0);
t.StoreElement(access, t.PointerConstant(smis),
- t.Int32Constant(static_cast<int>(j)), p0);
+ t.Int32Constant(static_cast<int>(j)),
+ t.Int32Constant(static_cast<int>(arraysize(smis))),
p0);
t.Return(p0);
t.LowerAllNodes();
@@ -422,8 +427,10 @@
SimplifiedLoweringTester<Object*> t;
Node* ptr = GetBaseNode(&t);
- Node* load = t.LoadElement(access, ptr, t.Int32Constant(from_index));
- t.StoreElement(access, ptr, t.Int32Constant(to_index), load);
+ Node* load = t.LoadElement(access, ptr, t.Int32Constant(from_index),
+ t.Int32Constant(num_elements));
+ t.StoreElement(access, ptr, t.Int32Constant(to_index),
+ t.Int32Constant(num_elements), load);
t.Return(t.jsgraph.TrueConstant());
t.LowerAllNodes();
t.GenerateCode();
@@ -633,11 +640,13 @@
JSGraph jsgraph;
Node* p0;
Node* p1;
+ Node* p2;
Node* start;
Node* end;
Node* ret;
- explicit TestingGraph(Type* p0_type, Type* p1_type = Type::None())
+ explicit TestingGraph(Type* p0_type, Type* p1_type = Type::None(),
+ Type* p2_type = Type::None())
: GraphAndBuilders(main_zone()),
typer(main_zone()),
javascript(main_zone()),
@@ -650,8 +659,10 @@
graph()->SetEnd(end);
p0 = graph()->NewNode(common()->Parameter(0), start);
p1 = graph()->NewNode(common()->Parameter(1), start);
+ p2 = graph()->NewNode(common()->Parameter(2), start);
NodeProperties::SetBounds(p0, Bounds(p0_type));
NodeProperties::SetBounds(p1, Bounds(p1_type));
+ NodeProperties::SetBounds(p2, Bounds(p2_type));
}
void CheckLoweringBinop(IrOpcode::Value expected, const Operator* op) {
@@ -1341,8 +1352,9 @@
ElementAccess access = {kTaggedBase, FixedArrayBase::kHeaderSize,
Type::Any(), machine_reps[i]};
- Node* load = t.graph()->NewNode(t.simplified()->LoadElement(access),
t.p0,
- t.p1, t.start);
+ Node* load =
+ t.graph()->NewNode(t.simplified()->LoadElement(access), t.p0, t.p1,
+ t.jsgraph.Int32Constant(1024), t.start);
Node* use = t.Use(load, machine_reps[i]);
t.Return(use);
t.Lower();
@@ -1365,7 +1377,8 @@
Node* val = t.ExampleWithOutput(machine_reps[i]);
Node* store = t.graph()->NewNode(t.simplified()->StoreElement(access),
t.p0,
- t.p1, val, t.start, t.start);
+ t.p1, t.jsgraph.Int32Constant(1024),
val,
+ t.start, t.start);
t.Effect(store);
t.Lower();
CHECK_EQ(IrOpcode::kStore, store->opcode());
@@ -1382,14 +1395,14 @@
TEST(InsertChangeForLoadElementIndex) {
- // LoadElement(obj: Tagged, index: kTypeInt32 | kRepTagged) =>
+ // LoadElement(obj: Tagged, index: kTypeInt32 | kRepTagged, length) =>
// Load(obj, Int32Add(Int32Mul(ChangeTaggedToInt32(index), #k), #k))
- TestingGraph t(Type::Any(), Type::Signed32());
+ TestingGraph t(Type::Any(), Type::Signed32(), Type::Any());
ElementAccess access = {kTaggedBase, FixedArrayBase::kHeaderSize,
Type::Any(),
kMachAnyTagged};
Node* load = t.graph()->NewNode(t.simplified()->LoadElement(access),
t.p0,
- t.p1, t.start);
+ t.p1, t.p2, t.start);
t.Return(load);
t.Lower();
CHECK_EQ(IrOpcode::kLoad, load->opcode());
@@ -1401,14 +1414,14 @@
TEST(InsertChangeForStoreElementIndex) {
- // StoreElement(obj: Tagged, index: kTypeInt32 | kRepTagged, val) =>
+ // StoreElement(obj: Tagged, index: kTypeInt32 | kRepTagged, length,
val) =>
// Store(obj, Int32Add(Int32Mul(ChangeTaggedToInt32(index), #k), #k),
val)
- TestingGraph t(Type::Any(), Type::Signed32());
+ TestingGraph t(Type::Any(), Type::Signed32(), Type::Any());
ElementAccess access = {kTaggedBase, FixedArrayBase::kHeaderSize,
Type::Any(),
kMachAnyTagged};
Node* store =
- t.graph()->NewNode(t.simplified()->StoreElement(access), t.p0, t.p1,
+ t.graph()->NewNode(t.simplified()->StoreElement(access), t.p0, t.p1,
t.p2,
t.jsgraph.TrueConstant(), t.start, t.start);
t.Effect(store);
t.Lower();
@@ -1422,12 +1435,12 @@
TEST(InsertChangeForLoadElement) {
// TODO(titzer): test all load/store representation change insertions.
- TestingGraph t(Type::Any(), Type::Signed32());
+ TestingGraph t(Type::Any(), Type::Signed32(), Type::Any());
ElementAccess access = {kTaggedBase, FixedArrayBase::kHeaderSize,
Type::Any(),
kMachFloat64};
Node* load = t.graph()->NewNode(t.simplified()->LoadElement(access),
t.p0,
- t.p1, t.start);
+ t.p1, t.p1, t.start);
t.Return(load);
t.Lower();
CHECK_EQ(IrOpcode::kLoad, load->opcode());
@@ -1454,13 +1467,13 @@
TEST(InsertChangeForStoreElement) {
// TODO(titzer): test all load/store representation change insertions.
- TestingGraph t(Type::Any(), Type::Signed32());
+ TestingGraph t(Type::Any(), Type::Signed32(), Type::Any());
ElementAccess access = {kTaggedBase, FixedArrayBase::kHeaderSize,
Type::Any(),
kMachFloat64};
- Node* store =
- t.graph()->NewNode(t.simplified()->StoreElement(access), t.p0,
- t.jsgraph.Int32Constant(0), t.p1, t.start,
t.start);
+ Node* store = t.graph()->NewNode(t.simplified()->StoreElement(access),
t.p0,
+ t.jsgraph.Int32Constant(0), t.p2, t.p1,
+ t.start, t.start);
t.Effect(store);
t.Lower();
--
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
---
You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/d/optout.