| 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 |