Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(244)

Side by Side Diff: test/cctest/compiler/test-js-context-specialization.cc

Issue 1112343002: [test] Remove DirectGraphBuilder helper. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@local_cleanup-test-machine-call-helper
Patch Set: Rebased. Created 5 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « test/cctest/compiler/graph-builder-tester.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2014 the V8 project authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/compiler/js-context-specialization.h" 5 #include "src/compiler/js-context-specialization.h"
6 #include "src/compiler/js-operator.h" 6 #include "src/compiler/js-operator.h"
7 #include "src/compiler/node-matchers.h" 7 #include "src/compiler/node-matchers.h"
8 #include "src/compiler/node-properties.h" 8 #include "src/compiler/node-properties.h"
9 #include "src/compiler/source-position.h" 9 #include "src/compiler/source-position.h"
10 #include "test/cctest/cctest.h" 10 #include "test/cctest/cctest.h"
11 #include "test/cctest/compiler/function-tester.h" 11 #include "test/cctest/compiler/function-tester.h"
12 #include "test/cctest/compiler/graph-builder-tester.h" 12 #include "test/cctest/compiler/graph-builder-tester.h"
13 13
14 using namespace v8::internal; 14 using namespace v8::internal;
15 using namespace v8::internal::compiler; 15 using namespace v8::internal::compiler;
16 16
17 class ContextSpecializationTester : public HandleAndZoneScope, 17 class ContextSpecializationTester : public HandleAndZoneScope {
18 public DirectGraphBuilder {
19 public: 18 public:
20 ContextSpecializationTester() 19 ContextSpecializationTester()
21 : DirectGraphBuilder(main_isolate(), 20 : graph_(new (main_zone()) Graph(main_zone())),
22 new (main_zone()) Graph(main_zone())),
23 common_(main_zone()), 21 common_(main_zone()),
24 javascript_(main_zone()), 22 javascript_(main_zone()),
25 machine_(main_zone()), 23 machine_(main_zone()),
26 simplified_(main_zone()), 24 simplified_(main_zone()),
27 jsgraph_(main_isolate(), graph(), common(), &javascript_, &machine_) {} 25 jsgraph_(main_isolate(), graph(), common(), &javascript_, &machine_) {}
28 26
29 Factory* factory() { return main_isolate()->factory(); } 27 Factory* factory() { return main_isolate()->factory(); }
30 CommonOperatorBuilder* common() { return &common_; } 28 CommonOperatorBuilder* common() { return &common_; }
31 JSOperatorBuilder* javascript() { return &javascript_; } 29 JSOperatorBuilder* javascript() { return &javascript_; }
32 SimplifiedOperatorBuilder* simplified() { return &simplified_; } 30 SimplifiedOperatorBuilder* simplified() { return &simplified_; }
33 JSGraph* jsgraph() { return &jsgraph_; } 31 JSGraph* jsgraph() { return &jsgraph_; }
32 Graph* graph() { return graph_; }
34 33
35 private: 34 private:
35 Graph* graph_;
36 CommonOperatorBuilder common_; 36 CommonOperatorBuilder common_;
37 JSOperatorBuilder javascript_; 37 JSOperatorBuilder javascript_;
38 MachineOperatorBuilder machine_; 38 MachineOperatorBuilder machine_;
39 SimplifiedOperatorBuilder simplified_; 39 SimplifiedOperatorBuilder simplified_;
40 JSGraph jsgraph_; 40 JSGraph jsgraph_;
41 }; 41 };
42 42
43 43
44 TEST(ReduceJSLoadContext) { 44 TEST(ReduceJSLoadContext) {
45 ContextSpecializationTester t; 45 ContextSpecializationTester t;
46 46
47 Node* start = t.NewNode(t.common()->Start(0)); 47 Node* start = t.graph()->NewNode(t.common()->Start(0));
48 t.graph()->SetStart(start); 48 t.graph()->SetStart(start);
49 49
50 // Make a context and initialize it a bit for this test. 50 // Make a context and initialize it a bit for this test.
51 Handle<Context> native = t.factory()->NewNativeContext(); 51 Handle<Context> native = t.factory()->NewNativeContext();
52 Handle<Context> subcontext1 = t.factory()->NewNativeContext(); 52 Handle<Context> subcontext1 = t.factory()->NewNativeContext();
53 Handle<Context> subcontext2 = t.factory()->NewNativeContext(); 53 Handle<Context> subcontext2 = t.factory()->NewNativeContext();
54 subcontext2->set_previous(*subcontext1); 54 subcontext2->set_previous(*subcontext1);
55 subcontext1->set_previous(*native); 55 subcontext1->set_previous(*native);
56 Handle<Object> expected = t.factory()->InternalizeUtf8String("gboy!"); 56 Handle<Object> expected = t.factory()->InternalizeUtf8String("gboy!");
57 const int slot = Context::GLOBAL_OBJECT_INDEX; 57 const int slot = Context::GLOBAL_OBJECT_INDEX;
58 native->set(slot, *expected); 58 native->set(slot, *expected);
59 59
60 Node* const_context = t.jsgraph()->Constant(native); 60 Node* const_context = t.jsgraph()->Constant(native);
61 Node* deep_const_context = t.jsgraph()->Constant(subcontext2); 61 Node* deep_const_context = t.jsgraph()->Constant(subcontext2);
62 Node* param_context = t.NewNode(t.common()->Parameter(0), start); 62 Node* param_context = t.graph()->NewNode(t.common()->Parameter(0), start);
63 JSContextSpecializer spec(t.jsgraph()); 63 JSContextSpecializer spec(t.jsgraph());
64 64
65 { 65 {
66 // Mutable slot, constant context, depth = 0 => do nothing. 66 // Mutable slot, constant context, depth = 0 => do nothing.
67 Node* load = t.NewNode(t.javascript()->LoadContext(0, 0, false), 67 Node* load = t.graph()->NewNode(t.javascript()->LoadContext(0, 0, false),
68 const_context, const_context, start); 68 const_context, const_context, start);
69 Reduction r = spec.ReduceJSLoadContext(load); 69 Reduction r = spec.ReduceJSLoadContext(load);
70 CHECK(!r.Changed()); 70 CHECK(!r.Changed());
71 } 71 }
72 72
73 { 73 {
74 // Mutable slot, non-constant context, depth = 0 => do nothing. 74 // Mutable slot, non-constant context, depth = 0 => do nothing.
75 Node* load = t.NewNode(t.javascript()->LoadContext(0, 0, false), 75 Node* load = t.graph()->NewNode(t.javascript()->LoadContext(0, 0, false),
76 param_context, param_context, start); 76 param_context, param_context, start);
77 Reduction r = spec.ReduceJSLoadContext(load); 77 Reduction r = spec.ReduceJSLoadContext(load);
78 CHECK(!r.Changed()); 78 CHECK(!r.Changed());
79 } 79 }
80 80
81 { 81 {
82 // Mutable slot, constant context, depth > 0 => fold-in parent context. 82 // Mutable slot, constant context, depth > 0 => fold-in parent context.
83 Node* load = t.NewNode( 83 Node* load = t.graph()->NewNode(
84 t.javascript()->LoadContext(2, Context::GLOBAL_EVAL_FUN_INDEX, false), 84 t.javascript()->LoadContext(2, Context::GLOBAL_EVAL_FUN_INDEX, false),
85 deep_const_context, deep_const_context, start); 85 deep_const_context, deep_const_context, start);
86 Reduction r = spec.ReduceJSLoadContext(load); 86 Reduction r = spec.ReduceJSLoadContext(load);
87 CHECK(r.Changed()); 87 CHECK(r.Changed());
88 Node* new_context_input = NodeProperties::GetValueInput(r.replacement(), 0); 88 Node* new_context_input = NodeProperties::GetValueInput(r.replacement(), 0);
89 CHECK_EQ(IrOpcode::kHeapConstant, new_context_input->opcode()); 89 CHECK_EQ(IrOpcode::kHeapConstant, new_context_input->opcode());
90 HeapObjectMatcher<Context> match(new_context_input); 90 HeapObjectMatcher<Context> match(new_context_input);
91 CHECK_EQ(*native, *match.Value().handle()); 91 CHECK_EQ(*native, *match.Value().handle());
92 ContextAccess access = OpParameter<ContextAccess>(r.replacement()); 92 ContextAccess access = OpParameter<ContextAccess>(r.replacement());
93 CHECK_EQ(Context::GLOBAL_EVAL_FUN_INDEX, static_cast<int>(access.index())); 93 CHECK_EQ(Context::GLOBAL_EVAL_FUN_INDEX, static_cast<int>(access.index()));
94 CHECK_EQ(0, static_cast<int>(access.depth())); 94 CHECK_EQ(0, static_cast<int>(access.depth()));
95 CHECK_EQ(false, access.immutable()); 95 CHECK_EQ(false, access.immutable());
96 } 96 }
97 97
98 { 98 {
99 // Immutable slot, constant context, depth = 0 => specialize. 99 // Immutable slot, constant context, depth = 0 => specialize.
100 Node* load = t.NewNode(t.javascript()->LoadContext(0, slot, true), 100 Node* load = t.graph()->NewNode(t.javascript()->LoadContext(0, slot, true),
101 const_context, const_context, start); 101 const_context, const_context, start);
102 Reduction r = spec.ReduceJSLoadContext(load); 102 Reduction r = spec.ReduceJSLoadContext(load);
103 CHECK(r.Changed()); 103 CHECK(r.Changed());
104 CHECK(r.replacement() != load); 104 CHECK(r.replacement() != load);
105 105
106 HeapObjectMatcher<Object> match(r.replacement()); 106 HeapObjectMatcher<Object> match(r.replacement());
107 CHECK(match.HasValue()); 107 CHECK(match.HasValue());
108 CHECK_EQ(*expected, *match.Value().handle()); 108 CHECK_EQ(*expected, *match.Value().handle());
109 } 109 }
110 110
111 // TODO(titzer): test with other kinds of contexts, e.g. a function context. 111 // TODO(titzer): test with other kinds of contexts, e.g. a function context.
112 // TODO(sigurds): test that loads below create context are not optimized 112 // TODO(sigurds): test that loads below create context are not optimized
113 } 113 }
114 114
115 115
116 TEST(ReduceJSStoreContext) { 116 TEST(ReduceJSStoreContext) {
117 ContextSpecializationTester t; 117 ContextSpecializationTester t;
118 118
119 Node* start = t.NewNode(t.common()->Start(0)); 119 Node* start = t.graph()->NewNode(t.common()->Start(0));
120 t.graph()->SetStart(start); 120 t.graph()->SetStart(start);
121 121
122 // Make a context and initialize it a bit for this test. 122 // Make a context and initialize it a bit for this test.
123 Handle<Context> native = t.factory()->NewNativeContext(); 123 Handle<Context> native = t.factory()->NewNativeContext();
124 Handle<Context> subcontext1 = t.factory()->NewNativeContext(); 124 Handle<Context> subcontext1 = t.factory()->NewNativeContext();
125 Handle<Context> subcontext2 = t.factory()->NewNativeContext(); 125 Handle<Context> subcontext2 = t.factory()->NewNativeContext();
126 subcontext2->set_previous(*subcontext1); 126 subcontext2->set_previous(*subcontext1);
127 subcontext1->set_previous(*native); 127 subcontext1->set_previous(*native);
128 Handle<Object> expected = t.factory()->InternalizeUtf8String("gboy!"); 128 Handle<Object> expected = t.factory()->InternalizeUtf8String("gboy!");
129 const int slot = Context::GLOBAL_OBJECT_INDEX; 129 const int slot = Context::GLOBAL_OBJECT_INDEX;
130 native->set(slot, *expected); 130 native->set(slot, *expected);
131 131
132 Node* const_context = t.jsgraph()->Constant(native); 132 Node* const_context = t.jsgraph()->Constant(native);
133 Node* deep_const_context = t.jsgraph()->Constant(subcontext2); 133 Node* deep_const_context = t.jsgraph()->Constant(subcontext2);
134 Node* param_context = t.NewNode(t.common()->Parameter(0), start); 134 Node* param_context = t.graph()->NewNode(t.common()->Parameter(0), start);
135 JSContextSpecializer spec(t.jsgraph()); 135 JSContextSpecializer spec(t.jsgraph());
136 136
137 { 137 {
138 // Mutable slot, constant context, depth = 0 => do nothing. 138 // Mutable slot, constant context, depth = 0 => do nothing.
139 Node* load = t.NewNode(t.javascript()->StoreContext(0, 0), const_context, 139 Node* load = t.graph()->NewNode(t.javascript()->StoreContext(0, 0),
140 const_context, start); 140 const_context, const_context, start);
141 Reduction r = spec.ReduceJSStoreContext(load); 141 Reduction r = spec.ReduceJSStoreContext(load);
142 CHECK(!r.Changed()); 142 CHECK(!r.Changed());
143 } 143 }
144 144
145 { 145 {
146 // Mutable slot, non-constant context, depth = 0 => do nothing. 146 // Mutable slot, non-constant context, depth = 0 => do nothing.
147 Node* load = t.NewNode(t.javascript()->StoreContext(0, 0), param_context, 147 Node* load = t.graph()->NewNode(t.javascript()->StoreContext(0, 0),
148 param_context, start); 148 param_context, param_context, start);
149 Reduction r = spec.ReduceJSStoreContext(load); 149 Reduction r = spec.ReduceJSStoreContext(load);
150 CHECK(!r.Changed()); 150 CHECK(!r.Changed());
151 } 151 }
152 152
153 { 153 {
154 // Immutable slot, constant context, depth = 0 => do nothing. 154 // Immutable slot, constant context, depth = 0 => do nothing.
155 Node* load = t.NewNode(t.javascript()->StoreContext(0, slot), const_context, 155 Node* load = t.graph()->NewNode(t.javascript()->StoreContext(0, slot),
156 const_context, start); 156 const_context, const_context, start);
157 Reduction r = spec.ReduceJSStoreContext(load); 157 Reduction r = spec.ReduceJSStoreContext(load);
158 CHECK(!r.Changed()); 158 CHECK(!r.Changed());
159 } 159 }
160 160
161 { 161 {
162 // Mutable slot, constant context, depth > 0 => fold-in parent context. 162 // Mutable slot, constant context, depth > 0 => fold-in parent context.
163 Node* load = t.NewNode( 163 Node* load = t.graph()->NewNode(
164 t.javascript()->StoreContext(2, Context::GLOBAL_EVAL_FUN_INDEX), 164 t.javascript()->StoreContext(2, Context::GLOBAL_EVAL_FUN_INDEX),
165 deep_const_context, deep_const_context, start); 165 deep_const_context, deep_const_context, start);
166 Reduction r = spec.ReduceJSStoreContext(load); 166 Reduction r = spec.ReduceJSStoreContext(load);
167 CHECK(r.Changed()); 167 CHECK(r.Changed());
168 Node* new_context_input = NodeProperties::GetValueInput(r.replacement(), 0); 168 Node* new_context_input = NodeProperties::GetValueInput(r.replacement(), 0);
169 CHECK_EQ(IrOpcode::kHeapConstant, new_context_input->opcode()); 169 CHECK_EQ(IrOpcode::kHeapConstant, new_context_input->opcode());
170 HeapObjectMatcher<Context> match(new_context_input); 170 HeapObjectMatcher<Context> match(new_context_input);
171 CHECK_EQ(*native, *match.Value().handle()); 171 CHECK_EQ(*native, *match.Value().handle());
172 ContextAccess access = OpParameter<ContextAccess>(r.replacement()); 172 ContextAccess access = OpParameter<ContextAccess>(r.replacement());
173 CHECK_EQ(Context::GLOBAL_EVAL_FUN_INDEX, static_cast<int>(access.index())); 173 CHECK_EQ(Context::GLOBAL_EVAL_FUN_INDEX, static_cast<int>(access.index()));
174 CHECK_EQ(0, static_cast<int>(access.depth())); 174 CHECK_EQ(0, static_cast<int>(access.depth()));
175 CHECK_EQ(false, access.immutable()); 175 CHECK_EQ(false, access.immutable());
176 } 176 }
177 } 177 }
178 178
179 179
180 // TODO(titzer): factor out common code with effects checking in typed lowering. 180 // TODO(titzer): factor out common code with effects checking in typed lowering.
181 static void CheckEffectInput(Node* effect, Node* use) { 181 static void CheckEffectInput(Node* effect, Node* use) {
182 CHECK_EQ(effect, NodeProperties::GetEffectInput(use)); 182 CHECK_EQ(effect, NodeProperties::GetEffectInput(use));
183 } 183 }
184 184
185 185
186 TEST(SpecializeToContext) { 186 TEST(SpecializeToContext) {
187 ContextSpecializationTester t; 187 ContextSpecializationTester t;
188 188
189 Node* start = t.NewNode(t.common()->Start(0)); 189 Node* start = t.graph()->NewNode(t.common()->Start(0));
190 t.graph()->SetStart(start); 190 t.graph()->SetStart(start);
191 191
192 // Make a context and initialize it a bit for this test. 192 // Make a context and initialize it a bit for this test.
193 Handle<Context> native = t.factory()->NewNativeContext(); 193 Handle<Context> native = t.factory()->NewNativeContext();
194 Handle<Object> expected = t.factory()->InternalizeUtf8String("gboy!"); 194 Handle<Object> expected = t.factory()->InternalizeUtf8String("gboy!");
195 const int slot = Context::GLOBAL_OBJECT_INDEX; 195 const int slot = Context::GLOBAL_OBJECT_INDEX;
196 native->set(slot, *expected); 196 native->set(slot, *expected);
197 197
198 Node* const_context = t.jsgraph()->Constant(native); 198 Node* const_context = t.jsgraph()->Constant(native);
199 Node* param_context = t.NewNode(t.common()->Parameter(0), start); 199 Node* param_context = t.graph()->NewNode(t.common()->Parameter(0), start);
200 JSContextSpecializer spec(t.jsgraph()); 200 JSContextSpecializer spec(t.jsgraph());
201 201
202 { 202 {
203 // Check that specialization replaces values and forwards effects 203 // Check that specialization replaces values and forwards effects
204 // correctly, and folds values from constant and non-constant contexts 204 // correctly, and folds values from constant and non-constant contexts
205 Node* effect_in = start; 205 Node* effect_in = start;
206 Node* load = t.NewNode(t.javascript()->LoadContext(0, slot, true), 206 Node* load = t.graph()->NewNode(t.javascript()->LoadContext(0, slot, true),
207 const_context, const_context, effect_in); 207 const_context, const_context, effect_in);
208 208
209 209
210 Node* value_use = t.NewNode(t.simplified()->ChangeTaggedToInt32(), load); 210 Node* value_use =
211 Node* other_load = t.NewNode(t.javascript()->LoadContext(0, slot, true), 211 t.graph()->NewNode(t.simplified()->ChangeTaggedToInt32(), load);
212 param_context, param_context, load); 212 Node* other_load =
213 t.graph()->NewNode(t.javascript()->LoadContext(0, slot, true),
214 param_context, param_context, load);
213 Node* effect_use = other_load; 215 Node* effect_use = other_load;
214 Node* other_use = 216 Node* other_use =
215 t.NewNode(t.simplified()->ChangeTaggedToInt32(), other_load); 217 t.graph()->NewNode(t.simplified()->ChangeTaggedToInt32(), other_load);
216 218
217 Node* add = t.NewNode(t.javascript()->Add(LanguageMode::SLOPPY), value_use, 219 Node* add =
218 other_use, param_context, other_load, start); 220 t.graph()->NewNode(t.javascript()->Add(LanguageMode::SLOPPY), value_use,
221 other_use, param_context, other_load, start);
219 222
220 Node* ret = t.NewNode(t.common()->Return(), add, effect_use, start); 223 Node* ret =
221 Node* end = t.NewNode(t.common()->End(), ret); 224 t.graph()->NewNode(t.common()->Return(), add, effect_use, start);
225 Node* end = t.graph()->NewNode(t.common()->End(), ret);
222 USE(end); 226 USE(end);
223 t.graph()->SetEnd(end); 227 t.graph()->SetEnd(end);
224 228
225 // Double check the above graph is what we expect, or the test is broken. 229 // Double check the above graph is what we expect, or the test is broken.
226 CheckEffectInput(effect_in, load); 230 CheckEffectInput(effect_in, load);
227 CheckEffectInput(load, effect_use); 231 CheckEffectInput(load, effect_use);
228 232
229 // Perform the reduction on the entire graph. 233 // Perform the reduction on the entire graph.
230 GraphReducer graph_reducer(t.graph(), t.main_zone()); 234 GraphReducer graph_reducer(t.graph(), t.main_zone());
231 graph_reducer.AddReducer(&spec); 235 graph_reducer.AddReducer(&spec);
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
294 { 298 {
295 FunctionTester T( 299 FunctionTester T(
296 "(function() { if (false) { var x = 1; } function inc(a)" 300 "(function() { if (false) { var x = 1; } function inc(a)"
297 " { return a + x; } return inc; })()"); // x is undefined! 301 " { return a + x; } return inc; })()"); // x is undefined!
298 302
299 CHECK(T.Call(T.Val(0.0), T.Val(0.0)).ToHandleChecked()->IsNaN()); 303 CHECK(T.Call(T.Val(0.0), T.Val(0.0)).ToHandleChecked()->IsNaN());
300 CHECK(T.Call(T.Val(2.0), T.Val(0.0)).ToHandleChecked()->IsNaN()); 304 CHECK(T.Call(T.Val(2.0), T.Val(0.0)).ToHandleChecked()->IsNaN());
301 CHECK(T.Call(T.Val(-2.1), T.Val(0.0)).ToHandleChecked()->IsNaN()); 305 CHECK(T.Call(T.Val(-2.1), T.Val(0.0)).ToHandleChecked()->IsNaN());
302 } 306 }
303 } 307 }
OLDNEW
« no previous file with comments | « test/cctest/compiler/graph-builder-tester.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698