17d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org// Copyright 2014 the V8 project authors. All rights reserved. 27d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org// Use of this source code is governed by a BSD-style license that can be 37d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org// found in the LICENSE file. 47d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 57d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org#include "src/compiler/js-context-specialization.h" 67d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org#include "src/compiler/js-operator.h" 77d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org#include "src/compiler/node-matchers.h" 87d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org#include "src/compiler/node-properties-inl.h" 97d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org#include "src/compiler/source-position.h" 107d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org#include "src/compiler/typer.h" 117d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org#include "test/cctest/cctest.h" 127d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org#include "test/cctest/compiler/function-tester.h" 137d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org#include "test/cctest/compiler/graph-builder-tester.h" 147d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 157d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgusing namespace v8::internal; 167d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgusing namespace v8::internal::compiler; 177d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 181af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.orgclass ContextSpecializationTester : public HandleAndZoneScope, 191af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org public DirectGraphBuilder { 207d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org public: 217d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org ContextSpecializationTester() 227d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org : DirectGraphBuilder(new (main_zone()) Graph(main_zone())), 237d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org common_(main_zone()), 247d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org javascript_(main_zone()), 25b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org machine_(), 267d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org simplified_(main_zone()), 277d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org typer_(main_zone()), 28b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org jsgraph_(graph(), common(), &javascript_, &typer_, &machine_), 297d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org info_(main_isolate(), main_zone()) {} 307d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 317d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org Factory* factory() { return main_isolate()->factory(); } 327d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org CommonOperatorBuilder* common() { return &common_; } 337d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org JSOperatorBuilder* javascript() { return &javascript_; } 347d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org SimplifiedOperatorBuilder* simplified() { return &simplified_; } 357d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org JSGraph* jsgraph() { return &jsgraph_; } 367d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org CompilationInfo* info() { return &info_; } 377d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 387d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org private: 397d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org CommonOperatorBuilder common_; 407d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org JSOperatorBuilder javascript_; 41b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org MachineOperatorBuilder machine_; 427d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org SimplifiedOperatorBuilder simplified_; 437d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org Typer typer_; 447d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org JSGraph jsgraph_; 457d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org CompilationInfo info_; 467d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org}; 477d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 487d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 497d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgTEST(ReduceJSLoadContext) { 507d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org ContextSpecializationTester t; 517d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 523e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org Node* start = t.NewNode(t.common()->Start(0)); 537d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org t.graph()->SetStart(start); 547d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 557d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org // Make a context and initialize it a bit for this test. 567d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org Handle<Context> native = t.factory()->NewNativeContext(); 578640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org Handle<Context> subcontext1 = t.factory()->NewNativeContext(); 588640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org Handle<Context> subcontext2 = t.factory()->NewNativeContext(); 598640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org subcontext2->set_previous(*subcontext1); 608640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org subcontext1->set_previous(*native); 617d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org Handle<Object> expected = t.factory()->InternalizeUtf8String("gboy!"); 627d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org const int slot = Context::GLOBAL_OBJECT_INDEX; 637d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org native->set(slot, *expected); 647d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 657d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org Node* const_context = t.jsgraph()->Constant(native); 668640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org Node* deep_const_context = t.jsgraph()->Constant(subcontext2); 673e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org Node* param_context = t.NewNode(t.common()->Parameter(0), start); 687d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org JSContextSpecializer spec(t.info(), t.jsgraph(), const_context); 697d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 707d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org { 717d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org // Mutable slot, constant context, depth = 0 => do nothing. 727d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org Node* load = t.NewNode(t.javascript()->LoadContext(0, 0, false), 738640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org const_context, const_context, start); 747d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org Reduction r = spec.ReduceJSLoadContext(load); 757d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org CHECK(!r.Changed()); 767d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } 777d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 787d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org { 797d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org // Mutable slot, non-constant context, depth = 0 => do nothing. 807d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org Node* load = t.NewNode(t.javascript()->LoadContext(0, 0, false), 818640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org param_context, param_context, start); 827d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org Reduction r = spec.ReduceJSLoadContext(load); 837d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org CHECK(!r.Changed()); 847d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } 857d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 867d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org { 878640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org // Mutable slot, constant context, depth > 0 => fold-in parent context. 887d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org Node* load = t.NewNode( 897d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org t.javascript()->LoadContext(2, Context::GLOBAL_EVAL_FUN_INDEX, false), 908640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org deep_const_context, deep_const_context, start); 917d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org Reduction r = spec.ReduceJSLoadContext(load); 927d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org CHECK(r.Changed()); 938640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org Node* new_context_input = NodeProperties::GetValueInput(r.replacement(), 0); 948640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org CHECK_EQ(IrOpcode::kHeapConstant, new_context_input->opcode()); 95e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org HeapObjectMatcher<Context> match(new_context_input); 96e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org CHECK_EQ(*native, *match.Value().handle()); 971af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org ContextAccess access = OpParameter<ContextAccess>(r.replacement()); 987d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org CHECK_EQ(Context::GLOBAL_EVAL_FUN_INDEX, access.index()); 997d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org CHECK_EQ(0, access.depth()); 1007d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org CHECK_EQ(false, access.immutable()); 1017d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } 1027d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 1037d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org { 1048640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org // Immutable slot, constant context, depth = 0 => specialize. 1057d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org Node* load = t.NewNode(t.javascript()->LoadContext(0, slot, true), 1068640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org const_context, const_context, start); 1077d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org Reduction r = spec.ReduceJSLoadContext(load); 1087d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org CHECK(r.Changed()); 1097d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org CHECK(r.replacement() != load); 1107d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 111e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org HeapObjectMatcher<Object> match(r.replacement()); 1127d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org CHECK(match.HasValue()); 113e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org CHECK_EQ(*expected, *match.Value().handle()); 1147d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } 1157d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 1168640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org // TODO(titzer): test with other kinds of contexts, e.g. a function context. 1178640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org // TODO(sigurds): test that loads below create context are not optimized 1188640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org} 1198640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org 1208640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org 1218640107360766c74218cf16d51b714b1f2138839machenbach@chromium.orgTEST(ReduceJSStoreContext) { 1228640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org ContextSpecializationTester t; 1238640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org 1248640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org Node* start = t.NewNode(t.common()->Start(0)); 1258640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org t.graph()->SetStart(start); 1268640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org 1278640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org // Make a context and initialize it a bit for this test. 1288640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org Handle<Context> native = t.factory()->NewNativeContext(); 1298640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org Handle<Context> subcontext1 = t.factory()->NewNativeContext(); 1308640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org Handle<Context> subcontext2 = t.factory()->NewNativeContext(); 1318640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org subcontext2->set_previous(*subcontext1); 1328640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org subcontext1->set_previous(*native); 1338640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org Handle<Object> expected = t.factory()->InternalizeUtf8String("gboy!"); 1348640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org const int slot = Context::GLOBAL_OBJECT_INDEX; 1358640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org native->set(slot, *expected); 1368640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org 1378640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org Node* const_context = t.jsgraph()->Constant(native); 1388640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org Node* deep_const_context = t.jsgraph()->Constant(subcontext2); 1398640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org Node* param_context = t.NewNode(t.common()->Parameter(0), start); 1408640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org JSContextSpecializer spec(t.info(), t.jsgraph(), const_context); 1418640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org 1427d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org { 1438640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org // Mutable slot, constant context, depth = 0 => do nothing. 1448640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org Node* load = t.NewNode(t.javascript()->StoreContext(0, 0), const_context, 1458640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org const_context, start); 1468640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org Reduction r = spec.ReduceJSStoreContext(load); 1478640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org CHECK(!r.Changed()); 1488640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org } 1497d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 1508640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org { 1518640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org // Mutable slot, non-constant context, depth = 0 => do nothing. 1528640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org Node* load = t.NewNode(t.javascript()->StoreContext(0, 0), param_context, 1538640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org param_context, start); 1548640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org Reduction r = spec.ReduceJSStoreContext(load); 1558640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org CHECK(!r.Changed()); 1567d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } 1577d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 1588640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org { 1598640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org // Immutable slot, constant context, depth = 0 => do nothing. 1608640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org Node* load = t.NewNode(t.javascript()->StoreContext(0, slot), const_context, 1618640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org const_context, start); 1628640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org Reduction r = spec.ReduceJSStoreContext(load); 1638640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org CHECK(!r.Changed()); 1648640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org } 1658640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org 1668640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org { 1678640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org // Mutable slot, constant context, depth > 0 => fold-in parent context. 1688640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org Node* load = t.NewNode( 1698640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org t.javascript()->StoreContext(2, Context::GLOBAL_EVAL_FUN_INDEX), 1708640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org deep_const_context, deep_const_context, start); 1718640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org Reduction r = spec.ReduceJSStoreContext(load); 1728640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org CHECK(r.Changed()); 1738640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org Node* new_context_input = NodeProperties::GetValueInput(r.replacement(), 0); 1748640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org CHECK_EQ(IrOpcode::kHeapConstant, new_context_input->opcode()); 175e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org HeapObjectMatcher<Context> match(new_context_input); 176e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org CHECK_EQ(*native, *match.Value().handle()); 1771af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org ContextAccess access = OpParameter<ContextAccess>(r.replacement()); 1788640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org CHECK_EQ(Context::GLOBAL_EVAL_FUN_INDEX, access.index()); 1798640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org CHECK_EQ(0, access.depth()); 1808640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org CHECK_EQ(false, access.immutable()); 1818640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org } 1827d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org} 1837d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 1847d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 1857d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org// TODO(titzer): factor out common code with effects checking in typed lowering. 1867d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgstatic void CheckEffectInput(Node* effect, Node* use) { 1877d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org CHECK_EQ(effect, NodeProperties::GetEffectInput(use)); 1887d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org} 1897d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 1907d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 1917d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgTEST(SpecializeToContext) { 1927d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org ContextSpecializationTester t; 1937d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 1943e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org Node* start = t.NewNode(t.common()->Start(0)); 1957d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org t.graph()->SetStart(start); 1967d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 1977d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org // Make a context and initialize it a bit for this test. 1987d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org Handle<Context> native = t.factory()->NewNativeContext(); 1997d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org Handle<Object> expected = t.factory()->InternalizeUtf8String("gboy!"); 2007d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org const int slot = Context::GLOBAL_OBJECT_INDEX; 2017d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org native->set(slot, *expected); 2027d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org t.info()->SetContext(native); 2037d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 2047d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org Node* const_context = t.jsgraph()->Constant(native); 2053e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org Node* param_context = t.NewNode(t.common()->Parameter(0), start); 2067d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org JSContextSpecializer spec(t.info(), t.jsgraph(), const_context); 2077d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 2087d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org { 2097d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org // Check that SpecializeToContext() replaces values and forwards effects 2107d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org // correctly, and folds values from constant and non-constant contexts 2118640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org Node* effect_in = start; 2127d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org Node* load = t.NewNode(t.javascript()->LoadContext(0, slot, true), 2138640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org const_context, const_context, effect_in); 2147d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 2157d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 2161af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org Node* value_use = t.NewNode(t.simplified()->ChangeTaggedToInt32(), load); 2177d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org Node* other_load = t.NewNode(t.javascript()->LoadContext(0, slot, true), 2188640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org param_context, param_context, load); 2197d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org Node* effect_use = other_load; 2201af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org Node* other_use = 2211af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org t.NewNode(t.simplified()->ChangeTaggedToInt32(), other_load); 2227d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 2238640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org Node* add = t.NewNode(t.javascript()->Add(), value_use, other_use, 2248640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org param_context, other_load, start); 2258640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org 2268640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org Node* ret = t.NewNode(t.common()->Return(), add, effect_use, start); 2278640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org Node* end = t.NewNode(t.common()->End(), ret); 2288640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org USE(end); 2298640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org t.graph()->SetEnd(end); 2308640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org 2317d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org // Double check the above graph is what we expect, or the test is broken. 2327d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org CheckEffectInput(effect_in, load); 2337d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org CheckEffectInput(load, effect_use); 2347d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 2357d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org // Perform the substitution on the entire graph. 2367d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org spec.SpecializeToContext(); 2377d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 2387d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org // Effects should have been forwarded (not replaced with a value). 2397d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org CheckEffectInput(effect_in, effect_use); 2407d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 2417d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org // Use of {other_load} should not have been replaced. 2427d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org CHECK_EQ(other_load, other_use->InputAt(0)); 2437d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 2447d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org Node* replacement = value_use->InputAt(0); 245e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org HeapObjectMatcher<Object> match(replacement); 2467d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org CHECK(match.HasValue()); 247e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org CHECK_EQ(*expected, *match.Value().handle()); 2487d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } 2497d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org // TODO(titzer): clean up above test and test more complicated effects. 2507d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org} 2517d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 2527d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 2537d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgTEST(SpecializeJSFunction_ToConstant1) { 2547d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org FunctionTester T( 2557d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org "(function() { var x = 1; function inc(a)" 2567d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org " { return a + x; } return inc; })()"); 2577d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 2587d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org T.CheckCall(1.0, 0.0, 0.0); 2597d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org T.CheckCall(2.0, 1.0, 0.0); 2607d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org T.CheckCall(2.1, 1.1, 0.0); 2617d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org} 2627d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 2637d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 2647d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgTEST(SpecializeJSFunction_ToConstant2) { 2657d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org FunctionTester T( 2667d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org "(function() { var x = 1.5; var y = 2.25; var z = 3.75;" 2677d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org " function f(a) { return a - x + y - z; } return f; })()"); 2687d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 2697d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org T.CheckCall(-3.0, 0.0, 0.0); 2707d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org T.CheckCall(-2.0, 1.0, 0.0); 2717d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org T.CheckCall(-1.9, 1.1, 0.0); 2727d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org} 2737d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 2747d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 2757d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgTEST(SpecializeJSFunction_ToConstant3) { 2767d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org FunctionTester T( 2777d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org "(function() { var x = -11.5; function inc()" 2787d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org " { return (function(a) { return a + x; }); }" 2797d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org " return inc(); })()"); 2807d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 2817d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org T.CheckCall(-11.5, 0.0, 0.0); 2827d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org T.CheckCall(-10.5, 1.0, 0.0); 2837d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org T.CheckCall(-10.4, 1.1, 0.0); 2847d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org} 2857d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 2867d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 2877d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgTEST(SpecializeJSFunction_ToConstant_uninit) { 2887d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org { 2897d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org FunctionTester T( 2907d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org "(function() { if (false) { var x = 1; } function inc(a)" 2917d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org " { return x; } return inc; })()"); // x is undefined! 2927d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 2937d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org CHECK(T.Call(T.Val(0.0), T.Val(0.0)).ToHandleChecked()->IsUndefined()); 2947d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org CHECK(T.Call(T.Val(2.0), T.Val(0.0)).ToHandleChecked()->IsUndefined()); 2957d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org CHECK(T.Call(T.Val(-2.1), T.Val(0.0)).ToHandleChecked()->IsUndefined()); 2967d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } 2977d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 2987d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org { 2997d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org FunctionTester T( 3007d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org "(function() { if (false) { var x = 1; } function inc(a)" 3017d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org " { return a + x; } return inc; })()"); // x is undefined! 3027d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 3037d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org CHECK(T.Call(T.Val(0.0), T.Val(0.0)).ToHandleChecked()->IsNaN()); 3047d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org CHECK(T.Call(T.Val(2.0), T.Val(0.0)).ToHandleChecked()->IsNaN()); 3057d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org CHECK(T.Call(T.Val(-2.1), T.Val(0.0)).ToHandleChecked()->IsNaN()); 3067d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } 3077d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org} 308