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

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

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

Powered by Google App Engine
This is Rietveld 408576698