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

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

Issue 1659463007: [turbofan] Remove untested no-deoptimization code path from JSGlobalObjectSpecialization. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 4 years, 10 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-object-specialization.h ('k') | src/compiler/pipeline.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2015 the V8 project authors. All rights reserved. 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 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-global-object-specialization.h" 5 #include "src/compiler/js-global-object-specialization.h"
6 6
7 #include "src/compilation-dependencies.h" 7 #include "src/compilation-dependencies.h"
8 #include "src/compiler/access-builder.h" 8 #include "src/compiler/access-builder.h"
9 #include "src/compiler/common-operator.h" 9 #include "src/compiler/common-operator.h"
10 #include "src/compiler/js-graph.h" 10 #include "src/compiler/js-graph.h"
11 #include "src/compiler/js-operator.h" 11 #include "src/compiler/js-operator.h"
12 #include "src/compiler/node-properties.h" 12 #include "src/compiler/node-properties.h"
13 #include "src/compiler/simplified-operator.h" 13 #include "src/compiler/simplified-operator.h"
14 #include "src/lookup.h" 14 #include "src/lookup.h"
15 #include "src/objects-inl.h" // TODO(mstarzinger): Temporary cycle breaker! 15 #include "src/objects-inl.h" // TODO(mstarzinger): Temporary cycle breaker!
16 #include "src/type-cache.h" 16 #include "src/type-cache.h"
17 17
18 namespace v8 { 18 namespace v8 {
19 namespace internal { 19 namespace internal {
20 namespace compiler { 20 namespace compiler {
21 21
22 struct JSGlobalObjectSpecialization::ScriptContextTableLookupResult { 22 struct JSGlobalObjectSpecialization::ScriptContextTableLookupResult {
23 Handle<Context> context; 23 Handle<Context> context;
24 bool immutable; 24 bool immutable;
25 int index; 25 int index;
26 }; 26 };
27 27
28 28
29 JSGlobalObjectSpecialization::JSGlobalObjectSpecialization( 29 JSGlobalObjectSpecialization::JSGlobalObjectSpecialization(
30 Editor* editor, JSGraph* jsgraph, Flags flags, 30 Editor* editor, JSGraph* jsgraph,
31 MaybeHandle<Context> native_context, CompilationDependencies* dependencies) 31 MaybeHandle<Context> native_context, CompilationDependencies* dependencies)
32 : AdvancedReducer(editor), 32 : AdvancedReducer(editor),
33 jsgraph_(jsgraph), 33 jsgraph_(jsgraph),
34 flags_(flags),
35 native_context_(native_context), 34 native_context_(native_context),
36 dependencies_(dependencies), 35 dependencies_(dependencies),
37 type_cache_(TypeCache::Get()) {} 36 type_cache_(TypeCache::Get()) {}
38 37
39 38
40 Reduction JSGlobalObjectSpecialization::Reduce(Node* node) { 39 Reduction JSGlobalObjectSpecialization::Reduce(Node* node) {
41 switch (node->opcode()) { 40 switch (node->opcode()) {
42 case IrOpcode::kJSLoadGlobal: 41 case IrOpcode::kJSLoadGlobal:
43 return ReduceJSLoadGlobal(node); 42 return ReduceJSLoadGlobal(node);
44 case IrOpcode::kJSStoreGlobal: 43 case IrOpcode::kJSStoreGlobal:
45 return ReduceJSStoreGlobal(node); 44 return ReduceJSStoreGlobal(node);
46 default: 45 default:
47 break; 46 break;
48 } 47 }
49 return NoChange(); 48 return NoChange();
50 } 49 }
51 50
52
53 Reduction JSGlobalObjectSpecialization::ReduceJSLoadGlobal(Node* node) { 51 Reduction JSGlobalObjectSpecialization::ReduceJSLoadGlobal(Node* node) {
54 DCHECK_EQ(IrOpcode::kJSLoadGlobal, node->opcode()); 52 DCHECK_EQ(IrOpcode::kJSLoadGlobal, node->opcode());
55 Handle<Name> name = LoadGlobalParametersOf(node->op()).name(); 53 Handle<Name> name = LoadGlobalParametersOf(node->op()).name();
56 Node* effect = NodeProperties::GetEffectInput(node); 54 Node* effect = NodeProperties::GetEffectInput(node);
57 Node* control = NodeProperties::GetControlInput(node); 55 Node* control = NodeProperties::GetControlInput(node);
58 56
59 // Retrieve the global object from the given {node}. 57 // Retrieve the global object from the given {node}.
60 Handle<JSGlobalObject> global_object; 58 Handle<JSGlobalObject> global_object;
61 if (!GetGlobalObject(node).ToHandle(&global_object)) return NoChange(); 59 if (!GetGlobalObject(node).ToHandle(&global_object)) return NoChange();
62 60
(...skipping 18 matching lines...) Expand all
81 Handle<Object> property_cell_value(property_cell->value(), isolate()); 79 Handle<Object> property_cell_value(property_cell->value(), isolate());
82 80
83 // Load from non-configurable, read-only data property on the global 81 // Load from non-configurable, read-only data property on the global
84 // object can be constant-folded, even without deoptimization support. 82 // object can be constant-folded, even without deoptimization support.
85 if (!property_details.IsConfigurable() && property_details.IsReadOnly()) { 83 if (!property_details.IsConfigurable() && property_details.IsReadOnly()) {
86 Node* value = jsgraph()->Constant(property_cell_value); 84 Node* value = jsgraph()->Constant(property_cell_value);
87 ReplaceWithValue(node, value); 85 ReplaceWithValue(node, value);
88 return Replace(value); 86 return Replace(value);
89 } 87 }
90 88
91 // Load from non-configurable, data property on the global can be lowered to 89 // Record a code dependency on the cell if we can benefit from the
92 // a field load, even without deoptimization, because the property cannot be 90 // additional feedback, or the global property is configurable (i.e.
93 // deleted or reconfigured to an accessor/interceptor property. Yet, if 91 // can be deleted or reconfigured to an accessor property).
94 // deoptimization support is available, we can constant-fold certain global 92 if (property_details.cell_type() != PropertyCellType::kMutable ||
95 // properties or at least lower them to field loads annotated with more 93 property_details.IsConfigurable()) {
96 // precise type feedback. 94 dependencies()->AssumePropertyCell(property_cell);
95 }
96
97 // Load from constant/undefined global property can be constant-folded.
98 if (property_details.cell_type() == PropertyCellType::kConstant ||
99 property_details.cell_type() == PropertyCellType::kUndefined) {
100 Node* value = jsgraph()->Constant(property_cell_value);
101 ReplaceWithValue(node, value);
102 return Replace(value);
103 }
104
105 // Load from constant type cell can benefit from type feedback.
97 Type* property_cell_value_type = Type::Tagged(); 106 Type* property_cell_value_type = Type::Tagged();
98 if (flags() & kDeoptimizationEnabled) { 107 if (property_details.cell_type() == PropertyCellType::kConstantType) {
99 // Record a code dependency on the cell if we can benefit from the 108 // Compute proper type based on the current value in the cell.
100 // additional feedback, or the global property is configurable (i.e. 109 if (property_cell_value->IsSmi()) {
101 // can be deleted or reconfigured to an accessor property). 110 property_cell_value_type = type_cache_.kSmi;
102 if (property_details.cell_type() != PropertyCellType::kMutable || 111 } else if (property_cell_value->IsNumber()) {
103 property_details.IsConfigurable()) { 112 property_cell_value_type = type_cache_.kHeapNumber;
104 dependencies()->AssumePropertyCell(property_cell); 113 } else {
114 Handle<Map> property_cell_value_map(
115 Handle<HeapObject>::cast(property_cell_value)->map(), isolate());
116 property_cell_value_type =
117 Type::Class(property_cell_value_map, graph()->zone());
105 } 118 }
106
107 // Load from constant/undefined global property can be constant-folded.
108 if ((property_details.cell_type() == PropertyCellType::kConstant ||
109 property_details.cell_type() == PropertyCellType::kUndefined)) {
110 Node* value = jsgraph()->Constant(property_cell_value);
111 ReplaceWithValue(node, value);
112 return Replace(value);
113 }
114
115 // Load from constant type cell can benefit from type feedback.
116 if (property_details.cell_type() == PropertyCellType::kConstantType) {
117 // Compute proper type based on the current value in the cell.
118 if (property_cell_value->IsSmi()) {
119 property_cell_value_type = type_cache_.kSmi;
120 } else if (property_cell_value->IsNumber()) {
121 property_cell_value_type = type_cache_.kHeapNumber;
122 } else {
123 Handle<Map> property_cell_value_map(
124 Handle<HeapObject>::cast(property_cell_value)->map(), isolate());
125 property_cell_value_type =
126 Type::Class(property_cell_value_map, graph()->zone());
127 }
128 }
129 } else if (property_details.IsConfigurable()) {
130 // Access to configurable global properties requires deoptimization support.
131 return NoChange();
132 } 119 }
133 Node* value = effect = graph()->NewNode( 120 Node* value = effect = graph()->NewNode(
134 simplified()->LoadField( 121 simplified()->LoadField(
135 AccessBuilder::ForPropertyCellValue(property_cell_value_type)), 122 AccessBuilder::ForPropertyCellValue(property_cell_value_type)),
136 jsgraph()->HeapConstant(property_cell), effect, control); 123 jsgraph()->HeapConstant(property_cell), effect, control);
137 ReplaceWithValue(node, value, effect, control); 124 ReplaceWithValue(node, value, effect, control);
138 return Replace(value); 125 return Replace(value);
139 } 126 }
140 127
141 128
(...skipping 29 matching lines...) Expand all
171 PropertyDetails property_details = property_cell->property_details(); 158 PropertyDetails property_details = property_cell->property_details();
172 Handle<Object> property_cell_value(property_cell->value(), isolate()); 159 Handle<Object> property_cell_value(property_cell->value(), isolate());
173 160
174 // Don't even bother trying to lower stores to read-only data properties. 161 // Don't even bother trying to lower stores to read-only data properties.
175 if (property_details.IsReadOnly()) return NoChange(); 162 if (property_details.IsReadOnly()) return NoChange();
176 switch (property_details.cell_type()) { 163 switch (property_details.cell_type()) {
177 case PropertyCellType::kUndefined: { 164 case PropertyCellType::kUndefined: {
178 return NoChange(); 165 return NoChange();
179 } 166 }
180 case PropertyCellType::kConstant: { 167 case PropertyCellType::kConstant: {
181 // Store to constant property cell requires deoptimization support, 168 // Record a code dependency on the cell, and just deoptimize if the new
182 // because we might even need to eager deoptimize for mismatch. 169 // value doesn't match the previous value stored inside the cell.
183 if (!(flags() & kDeoptimizationEnabled)) return NoChange();
184 dependencies()->AssumePropertyCell(property_cell); 170 dependencies()->AssumePropertyCell(property_cell);
185 Node* check = 171 Node* check =
186 graph()->NewNode(simplified()->ReferenceEqual(Type::Tagged()), value, 172 graph()->NewNode(simplified()->ReferenceEqual(Type::Tagged()), value,
187 jsgraph()->Constant(property_cell_value)); 173 jsgraph()->Constant(property_cell_value));
188 Node* branch = 174 Node* branch =
189 graph()->NewNode(common()->Branch(BranchHint::kTrue), check, control); 175 graph()->NewNode(common()->Branch(BranchHint::kTrue), check, control);
190 Node* if_false = graph()->NewNode(common()->IfFalse(), branch); 176 Node* if_false = graph()->NewNode(common()->IfFalse(), branch);
191 Node* deoptimize = 177 Node* deoptimize =
192 graph()->NewNode(common()->Deoptimize(DeoptimizeKind::kEager), 178 graph()->NewNode(common()->Deoptimize(DeoptimizeKind::kEager),
193 frame_state, effect, if_false); 179 frame_state, effect, if_false);
194 // TODO(bmeurer): This should be on the AdvancedReducer somehow. 180 // TODO(bmeurer): This should be on the AdvancedReducer somehow.
195 NodeProperties::MergeControlToEnd(graph(), common(), deoptimize); 181 NodeProperties::MergeControlToEnd(graph(), common(), deoptimize);
196 control = graph()->NewNode(common()->IfTrue(), branch); 182 control = graph()->NewNode(common()->IfTrue(), branch);
197 break; 183 break;
198 } 184 }
199 case PropertyCellType::kConstantType: { 185 case PropertyCellType::kConstantType: {
200 // Store to constant-type property cell requires deoptimization support, 186 // Record a code dependency on the cell, and just deoptimize if the new
201 // because we might even need to eager deoptimize for mismatch. 187 // values' type doesn't match the type of the previous value in the cell.
202 if (!(flags() & kDeoptimizationEnabled)) return NoChange();
203 dependencies()->AssumePropertyCell(property_cell); 188 dependencies()->AssumePropertyCell(property_cell);
204 Node* check = graph()->NewNode(simplified()->ObjectIsSmi(), value); 189 Node* check = graph()->NewNode(simplified()->ObjectIsSmi(), value);
205 Type* property_cell_value_type = Type::TaggedSigned(); 190 Type* property_cell_value_type = Type::TaggedSigned();
206 if (property_cell_value->IsHeapObject()) { 191 if (property_cell_value->IsHeapObject()) {
207 // Deoptimize if the {value} is a Smi. 192 // Deoptimize if the {value} is a Smi.
208 Node* branch = graph()->NewNode(common()->Branch(BranchHint::kFalse), 193 Node* branch = graph()->NewNode(common()->Branch(BranchHint::kFalse),
209 check, control); 194 check, control);
210 Node* if_true = graph()->NewNode(common()->IfTrue(), branch); 195 Node* if_true = graph()->NewNode(common()->IfTrue(), branch);
211 Node* deoptimize = 196 Node* deoptimize =
212 graph()->NewNode(common()->Deoptimize(DeoptimizeKind::kEager), 197 graph()->NewNode(common()->Deoptimize(DeoptimizeKind::kEager),
(...skipping 23 matching lines...) Expand all
236 NodeProperties::MergeControlToEnd(graph(), common(), deoptimize); 221 NodeProperties::MergeControlToEnd(graph(), common(), deoptimize);
237 control = graph()->NewNode(common()->IfTrue(), branch); 222 control = graph()->NewNode(common()->IfTrue(), branch);
238 effect = graph()->NewNode( 223 effect = graph()->NewNode(
239 simplified()->StoreField( 224 simplified()->StoreField(
240 AccessBuilder::ForPropertyCellValue(property_cell_value_type)), 225 AccessBuilder::ForPropertyCellValue(property_cell_value_type)),
241 jsgraph()->HeapConstant(property_cell), value, effect, control); 226 jsgraph()->HeapConstant(property_cell), value, effect, control);
242 break; 227 break;
243 } 228 }
244 case PropertyCellType::kMutable: { 229 case PropertyCellType::kMutable: {
245 // Store to non-configurable, data property on the global can be lowered 230 // Store to non-configurable, data property on the global can be lowered
246 // to a field store, even without deoptimization, because the property 231 // to a field store, even without recording a code dependency on the cell,
247 // cannot be deleted or reconfigured to an accessor/interceptor property. 232 // because the property cannot be deleted or reconfigured to an accessor
233 // or interceptor property.
248 if (property_details.IsConfigurable()) { 234 if (property_details.IsConfigurable()) {
249 // With deoptimization support, we can lower stores even to configurable 235 // Protect lowering by recording a code dependency on the cell.
250 // data properties on the global object, by adding a code dependency on
251 // the cell.
252 if (!(flags() & kDeoptimizationEnabled)) return NoChange();
253 dependencies()->AssumePropertyCell(property_cell); 236 dependencies()->AssumePropertyCell(property_cell);
254 } 237 }
255 effect = graph()->NewNode( 238 effect = graph()->NewNode(
256 simplified()->StoreField(AccessBuilder::ForPropertyCellValue()), 239 simplified()->StoreField(AccessBuilder::ForPropertyCellValue()),
257 jsgraph()->HeapConstant(property_cell), value, effect, control); 240 jsgraph()->HeapConstant(property_cell), value, effect, control);
258 break; 241 break;
259 } 242 }
260 } 243 }
261 ReplaceWithValue(node, value, effect, control); 244 ReplaceWithValue(node, value, effect, control);
262 return Replace(value); 245 return Replace(value);
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
311 } 294 }
312 295
313 296
314 SimplifiedOperatorBuilder* JSGlobalObjectSpecialization::simplified() const { 297 SimplifiedOperatorBuilder* JSGlobalObjectSpecialization::simplified() const {
315 return jsgraph()->simplified(); 298 return jsgraph()->simplified();
316 } 299 }
317 300
318 } // namespace compiler 301 } // namespace compiler
319 } // namespace internal 302 } // namespace internal
320 } // namespace v8 303 } // namespace v8
OLDNEW
« no previous file with comments | « src/compiler/js-global-object-specialization.h ('k') | src/compiler/pipeline.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698