OLD | NEW |
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 { | 18 public DirectGraphBuilder { |
19 public: | 19 public: |
20 ContextSpecializationTester() | 20 ContextSpecializationTester() |
21 : DirectGraphBuilder(main_isolate(), | 21 : DirectGraphBuilder(main_isolate(), |
22 new (main_zone()) Graph(main_zone())), | 22 new (main_zone()) Graph(main_zone())), |
23 common_(main_zone()), | 23 common_(main_zone()), |
24 javascript_(main_zone()), | 24 javascript_(main_zone()), |
25 machine_(main_zone()), | 25 machine_(main_zone()), |
26 simplified_(main_zone()), | 26 simplified_(main_zone()), |
27 jsgraph_(main_isolate(), graph(), common(), &javascript_, &machine_), | 27 jsgraph_(main_isolate(), graph(), common(), &javascript_, &machine_) {} |
28 info_(main_isolate(), main_zone()) {} | |
29 | 28 |
30 Factory* factory() { return main_isolate()->factory(); } | 29 Factory* factory() { return main_isolate()->factory(); } |
31 CommonOperatorBuilder* common() { return &common_; } | 30 CommonOperatorBuilder* common() { return &common_; } |
32 JSOperatorBuilder* javascript() { return &javascript_; } | 31 JSOperatorBuilder* javascript() { return &javascript_; } |
33 SimplifiedOperatorBuilder* simplified() { return &simplified_; } | 32 SimplifiedOperatorBuilder* simplified() { return &simplified_; } |
34 JSGraph* jsgraph() { return &jsgraph_; } | 33 JSGraph* jsgraph() { return &jsgraph_; } |
35 CompilationInfo* info() { return &info_; } | |
36 | 34 |
37 private: | 35 private: |
38 CommonOperatorBuilder common_; | 36 CommonOperatorBuilder common_; |
39 JSOperatorBuilder javascript_; | 37 JSOperatorBuilder javascript_; |
40 MachineOperatorBuilder machine_; | 38 MachineOperatorBuilder machine_; |
41 SimplifiedOperatorBuilder simplified_; | 39 SimplifiedOperatorBuilder simplified_; |
42 JSGraph jsgraph_; | 40 JSGraph jsgraph_; |
43 CompilationInfo info_; | |
44 }; | 41 }; |
45 | 42 |
46 | 43 |
47 TEST(ReduceJSLoadContext) { | 44 TEST(ReduceJSLoadContext) { |
48 ContextSpecializationTester t; | 45 ContextSpecializationTester t; |
49 | 46 |
50 Node* start = t.NewNode(t.common()->Start(0)); | 47 Node* start = t.NewNode(t.common()->Start(0)); |
51 t.graph()->SetStart(start); | 48 t.graph()->SetStart(start); |
52 | 49 |
53 // Make a context and initialize it a bit for this test. | 50 // Make a context and initialize it a bit for this test. |
54 Handle<Context> native = t.factory()->NewNativeContext(); | 51 Handle<Context> native = t.factory()->NewNativeContext(); |
55 Handle<Context> subcontext1 = t.factory()->NewNativeContext(); | 52 Handle<Context> subcontext1 = t.factory()->NewNativeContext(); |
56 Handle<Context> subcontext2 = t.factory()->NewNativeContext(); | 53 Handle<Context> subcontext2 = t.factory()->NewNativeContext(); |
57 subcontext2->set_previous(*subcontext1); | 54 subcontext2->set_previous(*subcontext1); |
58 subcontext1->set_previous(*native); | 55 subcontext1->set_previous(*native); |
59 Handle<Object> expected = t.factory()->InternalizeUtf8String("gboy!"); | 56 Handle<Object> expected = t.factory()->InternalizeUtf8String("gboy!"); |
60 const int slot = Context::GLOBAL_OBJECT_INDEX; | 57 const int slot = Context::GLOBAL_OBJECT_INDEX; |
61 native->set(slot, *expected); | 58 native->set(slot, *expected); |
62 | 59 |
63 Node* const_context = t.jsgraph()->Constant(native); | 60 Node* const_context = t.jsgraph()->Constant(native); |
64 Node* deep_const_context = t.jsgraph()->Constant(subcontext2); | 61 Node* deep_const_context = t.jsgraph()->Constant(subcontext2); |
65 Node* param_context = t.NewNode(t.common()->Parameter(0), start); | 62 Node* param_context = t.NewNode(t.common()->Parameter(0), start); |
66 JSContextSpecializer spec(t.info(), t.jsgraph(), const_context); | 63 JSContextSpecializer spec(Handle<Context>(), t.jsgraph(), const_context); |
67 | 64 |
68 { | 65 { |
69 // Mutable slot, constant context, depth = 0 => do nothing. | 66 // Mutable slot, constant context, depth = 0 => do nothing. |
70 Node* load = t.NewNode(t.javascript()->LoadContext(0, 0, false), | 67 Node* load = t.NewNode(t.javascript()->LoadContext(0, 0, false), |
71 const_context, const_context, start); | 68 const_context, const_context, start); |
72 Reduction r = spec.ReduceJSLoadContext(load); | 69 Reduction r = spec.ReduceJSLoadContext(load); |
73 CHECK(!r.Changed()); | 70 CHECK(!r.Changed()); |
74 } | 71 } |
75 | 72 |
76 { | 73 { |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
128 Handle<Context> subcontext2 = t.factory()->NewNativeContext(); | 125 Handle<Context> subcontext2 = t.factory()->NewNativeContext(); |
129 subcontext2->set_previous(*subcontext1); | 126 subcontext2->set_previous(*subcontext1); |
130 subcontext1->set_previous(*native); | 127 subcontext1->set_previous(*native); |
131 Handle<Object> expected = t.factory()->InternalizeUtf8String("gboy!"); | 128 Handle<Object> expected = t.factory()->InternalizeUtf8String("gboy!"); |
132 const int slot = Context::GLOBAL_OBJECT_INDEX; | 129 const int slot = Context::GLOBAL_OBJECT_INDEX; |
133 native->set(slot, *expected); | 130 native->set(slot, *expected); |
134 | 131 |
135 Node* const_context = t.jsgraph()->Constant(native); | 132 Node* const_context = t.jsgraph()->Constant(native); |
136 Node* deep_const_context = t.jsgraph()->Constant(subcontext2); | 133 Node* deep_const_context = t.jsgraph()->Constant(subcontext2); |
137 Node* param_context = t.NewNode(t.common()->Parameter(0), start); | 134 Node* param_context = t.NewNode(t.common()->Parameter(0), start); |
138 JSContextSpecializer spec(t.info(), t.jsgraph(), const_context); | 135 JSContextSpecializer spec(Handle<Context>(), t.jsgraph(), const_context); |
139 | 136 |
140 { | 137 { |
141 // Mutable slot, constant context, depth = 0 => do nothing. | 138 // Mutable slot, constant context, depth = 0 => do nothing. |
142 Node* load = t.NewNode(t.javascript()->StoreContext(0, 0), const_context, | 139 Node* load = t.NewNode(t.javascript()->StoreContext(0, 0), const_context, |
143 const_context, start); | 140 const_context, start); |
144 Reduction r = spec.ReduceJSStoreContext(load); | 141 Reduction r = spec.ReduceJSStoreContext(load); |
145 CHECK(!r.Changed()); | 142 CHECK(!r.Changed()); |
146 } | 143 } |
147 | 144 |
148 { | 145 { |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
190 ContextSpecializationTester t; | 187 ContextSpecializationTester t; |
191 | 188 |
192 Node* start = t.NewNode(t.common()->Start(0)); | 189 Node* start = t.NewNode(t.common()->Start(0)); |
193 t.graph()->SetStart(start); | 190 t.graph()->SetStart(start); |
194 | 191 |
195 // Make a context and initialize it a bit for this test. | 192 // Make a context and initialize it a bit for this test. |
196 Handle<Context> native = t.factory()->NewNativeContext(); | 193 Handle<Context> native = t.factory()->NewNativeContext(); |
197 Handle<Object> expected = t.factory()->InternalizeUtf8String("gboy!"); | 194 Handle<Object> expected = t.factory()->InternalizeUtf8String("gboy!"); |
198 const int slot = Context::GLOBAL_OBJECT_INDEX; | 195 const int slot = Context::GLOBAL_OBJECT_INDEX; |
199 native->set(slot, *expected); | 196 native->set(slot, *expected); |
200 t.info()->SetContext(native); | |
201 | 197 |
202 Node* const_context = t.jsgraph()->Constant(native); | 198 Node* const_context = t.jsgraph()->Constant(native); |
203 Node* param_context = t.NewNode(t.common()->Parameter(0), start); | 199 Node* param_context = t.NewNode(t.common()->Parameter(0), start); |
204 JSContextSpecializer spec(t.info(), t.jsgraph(), const_context); | 200 JSContextSpecializer spec(native, t.jsgraph(), const_context); |
205 | 201 |
206 { | 202 { |
207 // Check that specialization replaces values and forwards effects | 203 // Check that specialization replaces values and forwards effects |
208 // correctly, and folds values from constant and non-constant contexts | 204 // correctly, and folds values from constant and non-constant contexts |
209 Node* effect_in = start; | 205 Node* effect_in = start; |
210 Node* load = t.NewNode(t.javascript()->LoadContext(0, slot, true), | 206 Node* load = t.NewNode(t.javascript()->LoadContext(0, slot, true), |
211 const_context, const_context, effect_in); | 207 const_context, const_context, effect_in); |
212 | 208 |
213 | 209 |
214 Node* value_use = t.NewNode(t.simplified()->ChangeTaggedToInt32(), load); | 210 Node* value_use = t.NewNode(t.simplified()->ChangeTaggedToInt32(), load); |
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
298 { | 294 { |
299 FunctionTester T( | 295 FunctionTester T( |
300 "(function() { if (false) { var x = 1; } function inc(a)" | 296 "(function() { if (false) { var x = 1; } function inc(a)" |
301 " { return a + x; } return inc; })()"); // x is undefined! | 297 " { return a + x; } return inc; })()"); // x is undefined! |
302 | 298 |
303 CHECK(T.Call(T.Val(0.0), T.Val(0.0)).ToHandleChecked()->IsNaN()); | 299 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()); | 300 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()); | 301 CHECK(T.Call(T.Val(-2.1), T.Val(0.0)).ToHandleChecked()->IsNaN()); |
306 } | 302 } |
307 } | 303 } |
OLD | NEW |