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

Side by Side Diff: src/compiler/js-global-specialization.cc

Issue 1387393002: [turbofan] Add initial support for global specialization. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@AstGraphBuilder
Patch Set: Fix typo. Created 5 years, 2 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/js-global-specialization.h ('k') | src/compiler/js-typed-lowering.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright 2015 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "src/compiler/js-global-specialization.h"
6
7 #include "src/compilation-dependencies.h"
8 #include "src/compiler/access-builder.h"
9 #include "src/compiler/js-graph.h"
10 #include "src/compiler/js-operator.h"
11 #include "src/contexts.h"
12 #include "src/lookup.h"
13 #include "src/objects-inl.h"
14
15 namespace v8 {
16 namespace internal {
17 namespace compiler {
18
19 JSGlobalSpecialization::JSGlobalSpecialization(
20 Editor* editor, JSGraph* jsgraph, Flags flags,
21 Handle<GlobalObject> global_object, CompilationDependencies* dependencies)
22 : AdvancedReducer(editor),
23 jsgraph_(jsgraph),
24 flags_(flags),
25 global_object_(global_object),
26 dependencies_(dependencies),
27 simplified_(graph()->zone()) {}
28
29
30 Reduction JSGlobalSpecialization::Reduce(Node* node) {
31 switch (node->opcode()) {
32 case IrOpcode::kJSLoadGlobal:
33 return ReduceJSLoadGlobal(node);
34 case IrOpcode::kJSStoreGlobal:
35 return ReduceJSStoreGlobal(node);
36 default:
37 break;
38 }
39 return NoChange();
40 }
41
42
43 Reduction JSGlobalSpecialization::ReduceJSLoadGlobal(Node* node) {
44 DCHECK_EQ(IrOpcode::kJSLoadGlobal, node->opcode());
45 Handle<Name> name = LoadGlobalParametersOf(node->op()).name();
46 Node* effect = NodeProperties::GetEffectInput(node);
47
48 // Try to lookup the name on the script context table first (lexical scoping).
49 if (name->IsString()) {
50 Handle<ScriptContextTable> script_context_table(
51 global_object()->native_context()->script_context_table());
52 ScriptContextTable::LookupResult result;
53 if (ScriptContextTable::Lookup(script_context_table,
54 Handle<String>::cast(name), &result)) {
55 Handle<Context> script_context = ScriptContextTable::GetContext(
56 script_context_table, result.context_index);
57 if (script_context->is_the_hole(result.slot_index)) {
58 // TODO(bmeurer): Is this relevant in practice?
59 return NoChange();
60 }
61 Node* context = jsgraph()->Constant(script_context);
62 Node* value = effect = graph()->NewNode(
63 javascript()->LoadContext(0, result.slot_index,
64 IsImmutableVariableMode(result.mode)),
65 context, context, effect);
66 return Replace(node, value, effect);
67 }
68 }
69
70 // Lookup on the global object instead.
71 LookupIterator it(global_object(), name, LookupIterator::OWN);
72 if (it.state() == LookupIterator::DATA) {
73 return ReduceLoadFromPropertyCell(node, it.GetPropertyCell());
74 }
75
76 return NoChange();
77 }
78
79
80 Reduction JSGlobalSpecialization::ReduceJSStoreGlobal(Node* node) {
81 DCHECK_EQ(IrOpcode::kJSStoreGlobal, node->opcode());
82 Handle<Name> name = StoreGlobalParametersOf(node->op()).name();
83 Node* value = NodeProperties::GetValueInput(node, 2);
84 Node* effect = NodeProperties::GetEffectInput(node);
85 Node* control = NodeProperties::GetControlInput(node);
86
87 // Try to lookup the name on the script context table first (lexical scoping).
88 if (name->IsString()) {
89 Handle<ScriptContextTable> script_context_table(
90 global_object()->native_context()->script_context_table());
91 ScriptContextTable::LookupResult result;
92 if (ScriptContextTable::Lookup(script_context_table,
93 Handle<String>::cast(name), &result)) {
94 if (IsImmutableVariableMode(result.mode)) return NoChange();
95 Handle<Context> script_context = ScriptContextTable::GetContext(
96 script_context_table, result.context_index);
97 if (script_context->is_the_hole(result.slot_index)) {
98 // TODO(bmeurer): Is this relevant in practice?
99 return NoChange();
100 }
101 Node* context = jsgraph()->Constant(script_context);
102 effect =
103 graph()->NewNode(javascript()->StoreContext(0, result.slot_index),
104 context, value, context, effect, control);
105 return Replace(node, value, effect, control);
106 }
107 }
108
109 // Lookup on the global object instead.
110 LookupIterator it(global_object(), name, LookupIterator::OWN);
111 if (it.state() == LookupIterator::DATA) {
112 return ReduceStoreToPropertyCell(node, it.GetPropertyCell());
113 }
114
115 return NoChange();
116 }
117
118
119 Reduction JSGlobalSpecialization::ReduceLoadFromPropertyCell(
120 Node* node, Handle<PropertyCell> property_cell) {
121 Node* effect = NodeProperties::GetEffectInput(node);
122 Node* control = NodeProperties::GetControlInput(node);
123 // We only specialize global data property access.
124 PropertyDetails property_details = property_cell->property_details();
125 DCHECK_EQ(kData, property_details.kind());
126 Handle<Object> property_cell_value(property_cell->value(), isolate());
127 DCHECK(!property_cell_value->IsTheHole());
128 // Load from non-configurable, read-only data property on the global
129 // object can be constant-folded, even without deoptimization support.
130 if (!property_details.IsConfigurable() && property_details.IsReadOnly()) {
131 return Replace(node, property_cell_value);
132 }
133 // Load from constant/undefined global property can be constant-folded
134 // with deoptimization support, by adding a code dependency on the cell.
135 if ((property_details.cell_type() == PropertyCellType::kConstant ||
136 property_details.cell_type() == PropertyCellType::kUndefined) &&
137 (flags() & kDeoptimizationEnabled)) {
138 dependencies()->AssumePropertyCell(property_cell);
139 return Replace(node, property_cell_value);
140 }
141 // Not much we can do if we run the generic pipeline here.
142 if (!(flags() & kTypingEnabled)) return NoChange();
143 // Load from constant type global property can benefit from representation
144 // (and map) feedback with deoptimization support (requires code dependency).
145 if (property_details.cell_type() == PropertyCellType::kConstantType &&
146 (flags() & kDeoptimizationEnabled)) {
147 dependencies()->AssumePropertyCell(property_cell);
148 Type* property_cell_value_type = Type::Any();
149 switch (property_cell->GetConstantType()) {
150 case PropertyCellConstantType::kSmi:
151 property_cell_value_type = Type::Intersect(
152 Type::SignedSmall(), Type::TaggedSigned(), graph()->zone());
153 break;
154 case PropertyCellConstantType::kStableMap: {
155 // TODO(bmeurer): Determine type based on the map's instance type.
156 property_cell_value_type = Type::TaggedPointer();
157 break;
158 }
159 }
160 Node* value = effect = graph()->NewNode(
161 simplified()->LoadField(
162 AccessBuilder::ForPropertyCellValue(property_cell_value_type)),
163 jsgraph()->Constant(property_cell), effect, control);
164 return Replace(node, value, effect);
165 }
166 // Load from non-configurable, data property on the global can be lowered to
167 // a field load, even without deoptimization, because the property cannot be
168 // deleted or reconfigured to an accessor/interceptor property.
169 if (property_details.IsConfigurable()) {
170 // With deoptimization support, we can lower loads even from configurable
171 // data properties on the global object, by adding a code dependency on
172 // the cell.
173 if (!(flags() & kDeoptimizationEnabled)) return NoChange();
174 dependencies()->AssumePropertyCell(property_cell);
175 }
176 Node* value = effect = graph()->NewNode(
177 simplified()->LoadField(AccessBuilder::ForPropertyCellValue()),
178 jsgraph()->Constant(property_cell), effect, control);
179 return Replace(node, value, effect);
180 }
181
182
183 Reduction JSGlobalSpecialization::ReduceStoreToPropertyCell(
184 Node* node, Handle<PropertyCell> property_cell) {
185 Node* value = NodeProperties::GetValueInput(node, 2);
186 Node* effect = NodeProperties::GetEffectInput(node);
187 Node* control = NodeProperties::GetControlInput(node);
188 // We only specialize global data property access.
189 PropertyDetails property_details = property_cell->property_details();
190 DCHECK_EQ(kData, property_details.kind());
191 Handle<Object> property_cell_value(property_cell->value(), isolate());
192 DCHECK(!property_cell_value->IsTheHole());
193 // Don't even bother trying to lower stores to read-only data properties.
194 if (property_details.IsReadOnly()) return NoChange();
195 // Not much we can do if we run the generic pipeline here.
196 if (!(flags() & kTypingEnabled)) return NoChange();
197 // TODO(bmeurer): For now we deal only with cells in mutable state.
198 if (property_details.cell_type() != PropertyCellType::kMutable) {
199 return NoChange();
200 }
201 // Store to non-configurable, data property on the global can be lowered to
202 // a field store, even without deoptimization, because the property cannot be
203 // deleted or reconfigured to an accessor/interceptor property.
204 if (property_details.IsConfigurable()) {
205 // With deoptimization support, we can lower stores even to configurable
206 // data properties on the global object, by adding a code dependency on
207 // the cell.
208 if (!(flags() & kDeoptimizationEnabled)) return NoChange();
209 dependencies()->AssumePropertyCell(property_cell);
210 }
211 effect = graph()->NewNode(
212 simplified()->StoreField(AccessBuilder::ForPropertyCellValue()),
213 jsgraph()->Constant(property_cell), value, effect, control);
214 return Replace(node, value, effect, control);
215 }
216
217
218 Reduction JSGlobalSpecialization::Replace(Node* node, Handle<Object> value) {
219 if (value->IsConsString()) {
220 value = String::Flatten(Handle<String>::cast(value), TENURED);
221 }
222 return Replace(node, jsgraph()->Constant(value));
223 }
224
225
226 Graph* JSGlobalSpecialization::graph() const { return jsgraph()->graph(); }
227
228
229 Isolate* JSGlobalSpecialization::isolate() const {
230 return jsgraph()->isolate();
231 }
232
233
234 JSOperatorBuilder* JSGlobalSpecialization::javascript() const {
235 return jsgraph()->javascript();
236 }
237
238 } // namespace compiler
239 } // namespace internal
240 } // namespace v8
OLDNEW
« no previous file with comments | « src/compiler/js-global-specialization.h ('k') | src/compiler/js-typed-lowering.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698