OLD | NEW |
| (Empty) |
1 // Copyright 2014 the V8 project authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 #include "src/compiler/access-builder.h" | |
6 #include "src/compiler/js-graph.h" | |
7 #include "src/compiler/js-operator.h" | |
8 #include "src/compiler/js-typed-lowering.h" | |
9 #include "src/compiler/machine-operator.h" | |
10 #include "src/compiler/node-properties-inl.h" | |
11 #include "src/compiler/typer.h" | |
12 #include "test/unittests/compiler/compiler-test-utils.h" | |
13 #include "test/unittests/compiler/graph-unittest.h" | |
14 | |
15 namespace v8 { | |
16 namespace internal { | |
17 namespace compiler { | |
18 | |
19 namespace { | |
20 | |
21 const ExternalArrayType kExternalArrayTypes[] = { | |
22 #define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size) kExternal##Type##Array, | |
23 TYPED_ARRAYS(TYPED_ARRAY_CASE) | |
24 #undef TYPED_ARRAY_CASE | |
25 }; | |
26 | |
27 | |
28 const StrictMode kStrictModes[] = {SLOPPY, STRICT}; | |
29 | |
30 } // namespace | |
31 | |
32 | |
33 class JSTypedLoweringTest : public GraphTest { | |
34 public: | |
35 JSTypedLoweringTest() : GraphTest(3), javascript_(zone()) {} | |
36 virtual ~JSTypedLoweringTest() {} | |
37 | |
38 protected: | |
39 Reduction Reduce(Node* node) { | |
40 Typer typer(zone()); | |
41 MachineOperatorBuilder machine; | |
42 JSGraph jsgraph(graph(), common(), javascript(), &typer, &machine); | |
43 JSTypedLowering reducer(&jsgraph); | |
44 return reducer.Reduce(node); | |
45 } | |
46 | |
47 Node* Parameter(Type* type, int index = 0) { | |
48 Node* node = graph()->NewNode(common()->Parameter(index), graph()->start()); | |
49 NodeProperties::SetBounds(node, Bounds(Type::None(), type)); | |
50 return node; | |
51 } | |
52 | |
53 Handle<JSArrayBuffer> NewArrayBuffer(void* bytes, size_t byte_length) { | |
54 Handle<JSArrayBuffer> buffer = factory()->NewJSArrayBuffer(); | |
55 Runtime::SetupArrayBuffer(isolate(), buffer, true, bytes, byte_length); | |
56 return buffer; | |
57 } | |
58 | |
59 JSOperatorBuilder* javascript() { return &javascript_; } | |
60 | |
61 private: | |
62 JSOperatorBuilder javascript_; | |
63 }; | |
64 | |
65 | |
66 // ----------------------------------------------------------------------------- | |
67 // JSLoadProperty | |
68 | |
69 | |
70 TEST_F(JSTypedLoweringTest, JSLoadPropertyFromExternalTypedArray) { | |
71 const size_t kLength = 17; | |
72 uint8_t backing_store[kLength * 8]; | |
73 Handle<JSArrayBuffer> buffer = | |
74 NewArrayBuffer(backing_store, arraysize(backing_store)); | |
75 TRACED_FOREACH(ExternalArrayType, type, kExternalArrayTypes) { | |
76 Handle<JSTypedArray> array = | |
77 factory()->NewJSTypedArray(type, buffer, kLength); | |
78 | |
79 Node* key = Parameter(Type::Integral32()); | |
80 Node* context = UndefinedConstant(); | |
81 Node* effect = graph()->start(); | |
82 Node* control = graph()->start(); | |
83 Node* node = graph()->NewNode(javascript()->LoadProperty(), | |
84 HeapConstant(array), key, context); | |
85 if (FLAG_turbo_deoptimization) { | |
86 node->AppendInput(zone(), UndefinedConstant()); | |
87 } | |
88 node->AppendInput(zone(), effect); | |
89 node->AppendInput(zone(), control); | |
90 Reduction r = Reduce(node); | |
91 | |
92 ASSERT_TRUE(r.Changed()); | |
93 EXPECT_THAT( | |
94 r.replacement(), | |
95 IsLoadElement( | |
96 AccessBuilder::ForTypedArrayElement(type, true), | |
97 IsLoadField( | |
98 AccessBuilder::ForJSArrayBufferBackingStore(), | |
99 IsHeapConstant(Unique<HeapObject>::CreateImmovable(buffer)), | |
100 effect), | |
101 key, IsInt32Constant(static_cast<int>(kLength)), effect, control)); | |
102 } | |
103 } | |
104 | |
105 | |
106 // ----------------------------------------------------------------------------- | |
107 // JSStoreProperty | |
108 | |
109 | |
110 TEST_F(JSTypedLoweringTest, JSStorePropertyToExternalTypedArray) { | |
111 const size_t kLength = 17; | |
112 uint8_t backing_store[kLength * 8]; | |
113 Handle<JSArrayBuffer> buffer = | |
114 NewArrayBuffer(backing_store, arraysize(backing_store)); | |
115 TRACED_FOREACH(ExternalArrayType, type, kExternalArrayTypes) { | |
116 TRACED_FOREACH(StrictMode, strict_mode, kStrictModes) { | |
117 Handle<JSTypedArray> array = | |
118 factory()->NewJSTypedArray(type, buffer, kLength); | |
119 | |
120 Node* key = Parameter(Type::Integral32()); | |
121 Node* value = Parameter(Type::Any()); | |
122 Node* context = UndefinedConstant(); | |
123 Node* effect = graph()->start(); | |
124 Node* control = graph()->start(); | |
125 Node* node = graph()->NewNode(javascript()->StoreProperty(strict_mode), | |
126 HeapConstant(array), key, value, context); | |
127 if (FLAG_turbo_deoptimization) { | |
128 node->AppendInput(zone(), UndefinedConstant()); | |
129 } | |
130 node->AppendInput(zone(), effect); | |
131 node->AppendInput(zone(), control); | |
132 Reduction r = Reduce(node); | |
133 | |
134 ASSERT_TRUE(r.Changed()); | |
135 EXPECT_THAT( | |
136 r.replacement(), | |
137 IsStoreElement( | |
138 AccessBuilder::ForTypedArrayElement(type, true), | |
139 IsLoadField( | |
140 AccessBuilder::ForJSArrayBufferBackingStore(), | |
141 IsHeapConstant(Unique<HeapObject>::CreateImmovable(buffer)), | |
142 effect), | |
143 key, IsInt32Constant(static_cast<int>(kLength)), value, effect, | |
144 control)); | |
145 } | |
146 } | |
147 } | |
148 | |
149 } // namespace compiler | |
150 } // namespace internal | |
151 } // namespace v8 | |
OLD | NEW |