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

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

Issue 1162903006: [turbofan] Turn JSContextSpecializer into an AdvancedReducer. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Mark slow test on ARM64. Created 5 years, 6 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 | « src/compiler/pipeline.cc ('k') | test/mjsunit/mjsunit.status » ('j') | 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: 18 public:
19 ContextSpecializationTester() 19 ContextSpecializationTester()
20 : graph_(new (main_zone()) Graph(main_zone())), 20 : graph_(new (main_zone()) Graph(main_zone())),
21 common_(main_zone()), 21 common_(main_zone()),
22 javascript_(main_zone()), 22 javascript_(main_zone()),
23 machine_(main_zone()), 23 machine_(main_zone()),
24 simplified_(main_zone()), 24 simplified_(main_zone()),
25 jsgraph_(main_isolate(), graph(), common(), &javascript_, &machine_) {} 25 jsgraph_(main_isolate(), graph(), common(), &javascript_, &machine_),
26 reducer_(main_zone(), graph()),
27 spec_(&reducer_, jsgraph()) {}
26 28
29 JSContextSpecializer* spec() { return &spec_; }
27 Factory* factory() { return main_isolate()->factory(); } 30 Factory* factory() { return main_isolate()->factory(); }
28 CommonOperatorBuilder* common() { return &common_; } 31 CommonOperatorBuilder* common() { return &common_; }
29 JSOperatorBuilder* javascript() { return &javascript_; } 32 JSOperatorBuilder* javascript() { return &javascript_; }
30 SimplifiedOperatorBuilder* simplified() { return &simplified_; } 33 SimplifiedOperatorBuilder* simplified() { return &simplified_; }
31 JSGraph* jsgraph() { return &jsgraph_; } 34 JSGraph* jsgraph() { return &jsgraph_; }
32 Graph* graph() { return graph_; } 35 Graph* graph() { return graph_; }
33 36
34 private: 37 private:
35 Graph* graph_; 38 Graph* graph_;
36 CommonOperatorBuilder common_; 39 CommonOperatorBuilder common_;
37 JSOperatorBuilder javascript_; 40 JSOperatorBuilder javascript_;
38 MachineOperatorBuilder machine_; 41 MachineOperatorBuilder machine_;
39 SimplifiedOperatorBuilder simplified_; 42 SimplifiedOperatorBuilder simplified_;
40 JSGraph jsgraph_; 43 JSGraph jsgraph_;
44 GraphReducer reducer_;
45 JSContextSpecializer spec_;
41 }; 46 };
42 47
43 48
44 TEST(ReduceJSLoadContext) { 49 TEST(ReduceJSLoadContext) {
45 ContextSpecializationTester t; 50 ContextSpecializationTester t;
46 51
47 Node* start = t.graph()->NewNode(t.common()->Start(0)); 52 Node* start = t.graph()->NewNode(t.common()->Start(0));
48 t.graph()->SetStart(start); 53 t.graph()->SetStart(start);
49 54
50 // Make a context and initialize it a bit for this test. 55 // Make a context and initialize it a bit for this test.
51 Handle<Context> native = t.factory()->NewNativeContext(); 56 Handle<Context> native = t.factory()->NewNativeContext();
52 Handle<Context> subcontext1 = t.factory()->NewNativeContext(); 57 Handle<Context> subcontext1 = t.factory()->NewNativeContext();
53 Handle<Context> subcontext2 = t.factory()->NewNativeContext(); 58 Handle<Context> subcontext2 = t.factory()->NewNativeContext();
54 subcontext2->set_previous(*subcontext1); 59 subcontext2->set_previous(*subcontext1);
55 subcontext1->set_previous(*native); 60 subcontext1->set_previous(*native);
56 Handle<Object> expected = t.factory()->InternalizeUtf8String("gboy!"); 61 Handle<Object> expected = t.factory()->InternalizeUtf8String("gboy!");
57 const int slot = Context::GLOBAL_OBJECT_INDEX; 62 const int slot = Context::GLOBAL_OBJECT_INDEX;
58 native->set(slot, *expected); 63 native->set(slot, *expected);
59 64
60 Node* const_context = t.jsgraph()->Constant(native); 65 Node* const_context = t.jsgraph()->Constant(native);
61 Node* deep_const_context = t.jsgraph()->Constant(subcontext2); 66 Node* deep_const_context = t.jsgraph()->Constant(subcontext2);
62 Node* param_context = t.graph()->NewNode(t.common()->Parameter(0), start); 67 Node* param_context = t.graph()->NewNode(t.common()->Parameter(0), start);
63 JSContextSpecializer spec(t.jsgraph());
64 68
65 { 69 {
66 // Mutable slot, constant context, depth = 0 => do nothing. 70 // Mutable slot, constant context, depth = 0 => do nothing.
67 Node* load = t.graph()->NewNode(t.javascript()->LoadContext(0, 0, false), 71 Node* load = t.graph()->NewNode(t.javascript()->LoadContext(0, 0, false),
68 const_context, const_context, start); 72 const_context, const_context, start);
69 Reduction r = spec.ReduceJSLoadContext(load); 73 Reduction r = t.spec()->ReduceJSLoadContext(load);
70 CHECK(!r.Changed()); 74 CHECK(!r.Changed());
71 } 75 }
72 76
73 { 77 {
74 // Mutable slot, non-constant context, depth = 0 => do nothing. 78 // Mutable slot, non-constant context, depth = 0 => do nothing.
75 Node* load = t.graph()->NewNode(t.javascript()->LoadContext(0, 0, false), 79 Node* load = t.graph()->NewNode(t.javascript()->LoadContext(0, 0, false),
76 param_context, param_context, start); 80 param_context, param_context, start);
77 Reduction r = spec.ReduceJSLoadContext(load); 81 Reduction r = t.spec()->ReduceJSLoadContext(load);
78 CHECK(!r.Changed()); 82 CHECK(!r.Changed());
79 } 83 }
80 84
81 { 85 {
82 // Mutable slot, constant context, depth > 0 => fold-in parent context. 86 // Mutable slot, constant context, depth > 0 => fold-in parent context.
83 Node* load = t.graph()->NewNode( 87 Node* load = t.graph()->NewNode(
84 t.javascript()->LoadContext(2, Context::GLOBAL_EVAL_FUN_INDEX, false), 88 t.javascript()->LoadContext(2, Context::GLOBAL_EVAL_FUN_INDEX, false),
85 deep_const_context, deep_const_context, start); 89 deep_const_context, deep_const_context, start);
86 Reduction r = spec.ReduceJSLoadContext(load); 90 Reduction r = t.spec()->ReduceJSLoadContext(load);
87 CHECK(r.Changed()); 91 CHECK(r.Changed());
88 Node* new_context_input = NodeProperties::GetValueInput(r.replacement(), 0); 92 Node* new_context_input = NodeProperties::GetValueInput(r.replacement(), 0);
89 CHECK_EQ(IrOpcode::kHeapConstant, new_context_input->opcode()); 93 CHECK_EQ(IrOpcode::kHeapConstant, new_context_input->opcode());
90 HeapObjectMatcher<Context> match(new_context_input); 94 HeapObjectMatcher<Context> match(new_context_input);
91 CHECK_EQ(*native, *match.Value().handle()); 95 CHECK_EQ(*native, *match.Value().handle());
92 ContextAccess access = OpParameter<ContextAccess>(r.replacement()); 96 ContextAccess access = OpParameter<ContextAccess>(r.replacement());
93 CHECK_EQ(Context::GLOBAL_EVAL_FUN_INDEX, static_cast<int>(access.index())); 97 CHECK_EQ(Context::GLOBAL_EVAL_FUN_INDEX, static_cast<int>(access.index()));
94 CHECK_EQ(0, static_cast<int>(access.depth())); 98 CHECK_EQ(0, static_cast<int>(access.depth()));
95 CHECK_EQ(false, access.immutable()); 99 CHECK_EQ(false, access.immutable());
96 } 100 }
97 101
98 { 102 {
99 // Immutable slot, constant context, depth = 0 => specialize. 103 // Immutable slot, constant context, depth = 0 => specialize.
100 Node* load = t.graph()->NewNode(t.javascript()->LoadContext(0, slot, true), 104 Node* load = t.graph()->NewNode(t.javascript()->LoadContext(0, slot, true),
101 const_context, const_context, start); 105 const_context, const_context, start);
102 Reduction r = spec.ReduceJSLoadContext(load); 106 Reduction r = t.spec()->ReduceJSLoadContext(load);
103 CHECK(r.Changed()); 107 CHECK(r.Changed());
104 CHECK(r.replacement() != load); 108 CHECK(r.replacement() != load);
105 109
106 HeapObjectMatcher<Object> match(r.replacement()); 110 HeapObjectMatcher<Object> match(r.replacement());
107 CHECK(match.HasValue()); 111 CHECK(match.HasValue());
108 CHECK_EQ(*expected, *match.Value().handle()); 112 CHECK_EQ(*expected, *match.Value().handle());
109 } 113 }
110 114
111 // TODO(titzer): test with other kinds of contexts, e.g. a function context. 115 // 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 116 // TODO(sigurds): test that loads below create context are not optimized
(...skipping 12 matching lines...) Expand all
125 Handle<Context> subcontext2 = t.factory()->NewNativeContext(); 129 Handle<Context> subcontext2 = t.factory()->NewNativeContext();
126 subcontext2->set_previous(*subcontext1); 130 subcontext2->set_previous(*subcontext1);
127 subcontext1->set_previous(*native); 131 subcontext1->set_previous(*native);
128 Handle<Object> expected = t.factory()->InternalizeUtf8String("gboy!"); 132 Handle<Object> expected = t.factory()->InternalizeUtf8String("gboy!");
129 const int slot = Context::GLOBAL_OBJECT_INDEX; 133 const int slot = Context::GLOBAL_OBJECT_INDEX;
130 native->set(slot, *expected); 134 native->set(slot, *expected);
131 135
132 Node* const_context = t.jsgraph()->Constant(native); 136 Node* const_context = t.jsgraph()->Constant(native);
133 Node* deep_const_context = t.jsgraph()->Constant(subcontext2); 137 Node* deep_const_context = t.jsgraph()->Constant(subcontext2);
134 Node* param_context = t.graph()->NewNode(t.common()->Parameter(0), start); 138 Node* param_context = t.graph()->NewNode(t.common()->Parameter(0), start);
135 JSContextSpecializer spec(t.jsgraph());
136 139
137 { 140 {
138 // Mutable slot, constant context, depth = 0 => do nothing. 141 // Mutable slot, constant context, depth = 0 => do nothing.
139 Node* load = t.graph()->NewNode(t.javascript()->StoreContext(0, 0), 142 Node* load = t.graph()->NewNode(t.javascript()->StoreContext(0, 0),
140 const_context, const_context, start); 143 const_context, const_context, start);
141 Reduction r = spec.ReduceJSStoreContext(load); 144 Reduction r = t.spec()->ReduceJSStoreContext(load);
142 CHECK(!r.Changed()); 145 CHECK(!r.Changed());
143 } 146 }
144 147
145 { 148 {
146 // Mutable slot, non-constant context, depth = 0 => do nothing. 149 // Mutable slot, non-constant context, depth = 0 => do nothing.
147 Node* load = t.graph()->NewNode(t.javascript()->StoreContext(0, 0), 150 Node* load = t.graph()->NewNode(t.javascript()->StoreContext(0, 0),
148 param_context, param_context, start); 151 param_context, param_context, start);
149 Reduction r = spec.ReduceJSStoreContext(load); 152 Reduction r = t.spec()->ReduceJSStoreContext(load);
150 CHECK(!r.Changed()); 153 CHECK(!r.Changed());
151 } 154 }
152 155
153 { 156 {
154 // Immutable slot, constant context, depth = 0 => do nothing. 157 // Immutable slot, constant context, depth = 0 => do nothing.
155 Node* load = t.graph()->NewNode(t.javascript()->StoreContext(0, slot), 158 Node* load = t.graph()->NewNode(t.javascript()->StoreContext(0, slot),
156 const_context, const_context, start); 159 const_context, const_context, start);
157 Reduction r = spec.ReduceJSStoreContext(load); 160 Reduction r = t.spec()->ReduceJSStoreContext(load);
158 CHECK(!r.Changed()); 161 CHECK(!r.Changed());
159 } 162 }
160 163
161 { 164 {
162 // Mutable slot, constant context, depth > 0 => fold-in parent context. 165 // Mutable slot, constant context, depth > 0 => fold-in parent context.
163 Node* load = t.graph()->NewNode( 166 Node* load = t.graph()->NewNode(
164 t.javascript()->StoreContext(2, Context::GLOBAL_EVAL_FUN_INDEX), 167 t.javascript()->StoreContext(2, Context::GLOBAL_EVAL_FUN_INDEX),
165 deep_const_context, deep_const_context, start); 168 deep_const_context, deep_const_context, start);
166 Reduction r = spec.ReduceJSStoreContext(load); 169 Reduction r = t.spec()->ReduceJSStoreContext(load);
167 CHECK(r.Changed()); 170 CHECK(r.Changed());
168 Node* new_context_input = NodeProperties::GetValueInput(r.replacement(), 0); 171 Node* new_context_input = NodeProperties::GetValueInput(r.replacement(), 0);
169 CHECK_EQ(IrOpcode::kHeapConstant, new_context_input->opcode()); 172 CHECK_EQ(IrOpcode::kHeapConstant, new_context_input->opcode());
170 HeapObjectMatcher<Context> match(new_context_input); 173 HeapObjectMatcher<Context> match(new_context_input);
171 CHECK_EQ(*native, *match.Value().handle()); 174 CHECK_EQ(*native, *match.Value().handle());
172 ContextAccess access = OpParameter<ContextAccess>(r.replacement()); 175 ContextAccess access = OpParameter<ContextAccess>(r.replacement());
173 CHECK_EQ(Context::GLOBAL_EVAL_FUN_INDEX, static_cast<int>(access.index())); 176 CHECK_EQ(Context::GLOBAL_EVAL_FUN_INDEX, static_cast<int>(access.index()));
174 CHECK_EQ(0, static_cast<int>(access.depth())); 177 CHECK_EQ(0, static_cast<int>(access.depth()));
175 CHECK_EQ(false, access.immutable()); 178 CHECK_EQ(false, access.immutable());
176 } 179 }
(...skipping 13 matching lines...) Expand all
190 t.graph()->SetStart(start); 193 t.graph()->SetStart(start);
191 194
192 // Make a context and initialize it a bit for this test. 195 // Make a context and initialize it a bit for this test.
193 Handle<Context> native = t.factory()->NewNativeContext(); 196 Handle<Context> native = t.factory()->NewNativeContext();
194 Handle<Object> expected = t.factory()->InternalizeUtf8String("gboy!"); 197 Handle<Object> expected = t.factory()->InternalizeUtf8String("gboy!");
195 const int slot = Context::GLOBAL_OBJECT_INDEX; 198 const int slot = Context::GLOBAL_OBJECT_INDEX;
196 native->set(slot, *expected); 199 native->set(slot, *expected);
197 200
198 Node* const_context = t.jsgraph()->Constant(native); 201 Node* const_context = t.jsgraph()->Constant(native);
199 Node* param_context = t.graph()->NewNode(t.common()->Parameter(0), start); 202 Node* param_context = t.graph()->NewNode(t.common()->Parameter(0), start);
200 JSContextSpecializer spec(t.jsgraph());
201 203
202 { 204 {
203 // Check that specialization replaces values and forwards effects 205 // Check that specialization replaces values and forwards effects
204 // correctly, and folds values from constant and non-constant contexts 206 // correctly, and folds values from constant and non-constant contexts
205 Node* effect_in = start; 207 Node* effect_in = start;
206 Node* load = t.graph()->NewNode(t.javascript()->LoadContext(0, slot, true), 208 Node* load = t.graph()->NewNode(t.javascript()->LoadContext(0, slot, true),
207 const_context, const_context, effect_in); 209 const_context, const_context, effect_in);
208 210
209 211
210 Node* value_use = 212 Node* value_use =
(...skipping 14 matching lines...) Expand all
225 Node* end = t.graph()->NewNode(t.common()->End(1), ret); 227 Node* end = t.graph()->NewNode(t.common()->End(1), ret);
226 USE(end); 228 USE(end);
227 t.graph()->SetEnd(end); 229 t.graph()->SetEnd(end);
228 230
229 // Double check the above graph is what we expect, or the test is broken. 231 // Double check the above graph is what we expect, or the test is broken.
230 CheckEffectInput(effect_in, load); 232 CheckEffectInput(effect_in, load);
231 CheckEffectInput(load, effect_use); 233 CheckEffectInput(load, effect_use);
232 234
233 // Perform the reduction on the entire graph. 235 // Perform the reduction on the entire graph.
234 GraphReducer graph_reducer(t.main_zone(), t.graph()); 236 GraphReducer graph_reducer(t.main_zone(), t.graph());
237 JSContextSpecializer spec(&graph_reducer, t.jsgraph());
235 graph_reducer.AddReducer(&spec); 238 graph_reducer.AddReducer(&spec);
236 graph_reducer.ReduceGraph(); 239 graph_reducer.ReduceGraph();
237 240
238 // Effects should have been forwarded (not replaced with a value). 241 // Effects should have been forwarded (not replaced with a value).
239 CheckEffectInput(effect_in, effect_use); 242 CheckEffectInput(effect_in, effect_use);
240 243
241 // Use of {other_load} should not have been replaced. 244 // Use of {other_load} should not have been replaced.
242 CHECK_EQ(other_load, other_use->InputAt(0)); 245 CHECK_EQ(other_load, other_use->InputAt(0));
243 246
244 Node* replacement = value_use->InputAt(0); 247 Node* replacement = value_use->InputAt(0);
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
298 { 301 {
299 FunctionTester T( 302 FunctionTester T(
300 "(function() { if (false) { var x = 1; } function inc(a)" 303 "(function() { if (false) { var x = 1; } function inc(a)"
301 " { return a + x; } return inc; })()"); // x is undefined! 304 " { return a + x; } return inc; })()"); // x is undefined!
302 305
303 CHECK(T.Call(T.Val(0.0), T.Val(0.0)).ToHandleChecked()->IsNaN()); 306 CHECK(T.Call(T.Val(0.0), T.Val(0.0)).ToHandleChecked()->IsNaN());
304 CHECK(T.Call(T.Val(2.0), T.Val(0.0)).ToHandleChecked()->IsNaN()); 307 CHECK(T.Call(T.Val(2.0), T.Val(0.0)).ToHandleChecked()->IsNaN());
305 CHECK(T.Call(T.Val(-2.1), T.Val(0.0)).ToHandleChecked()->IsNaN()); 308 CHECK(T.Call(T.Val(-2.1), T.Val(0.0)).ToHandleChecked()->IsNaN());
306 } 309 }
307 } 310 }
OLDNEW
« no previous file with comments | « src/compiler/pipeline.cc ('k') | test/mjsunit/mjsunit.status » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698