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

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

Issue 2604393002: [turbofan] Utilize maps from field type tracking to eliminate map checks. (Closed)
Patch Set: Created 3 years, 11 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-create-lowering.cc ('k') | src/compiler/js-native-context-specialization.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"
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
42 return ReduceJSStoreGlobal(node); 42 return ReduceJSStoreGlobal(node);
43 default: 43 default:
44 break; 44 break;
45 } 45 }
46 return NoChange(); 46 return NoChange();
47 } 47 }
48 48
49 namespace { 49 namespace {
50 50
51 FieldAccess ForPropertyCellValue(MachineRepresentation representation, 51 FieldAccess ForPropertyCellValue(MachineRepresentation representation,
52 Type* type, Handle<Name> name) { 52 Type* type, MaybeHandle<Map> map,
53 Handle<Name> name) {
53 WriteBarrierKind kind = kFullWriteBarrier; 54 WriteBarrierKind kind = kFullWriteBarrier;
54 if (representation == MachineRepresentation::kTaggedSigned) { 55 if (representation == MachineRepresentation::kTaggedSigned) {
55 kind = kNoWriteBarrier; 56 kind = kNoWriteBarrier;
56 } else if (representation == MachineRepresentation::kTaggedPointer) { 57 } else if (representation == MachineRepresentation::kTaggedPointer) {
57 kind = kPointerWriteBarrier; 58 kind = kPointerWriteBarrier;
58 } 59 }
59 MachineType r = MachineType::TypeForRepresentation(representation); 60 MachineType r = MachineType::TypeForRepresentation(representation);
60 FieldAccess access = {kTaggedBase, PropertyCell::kValueOffset, name, type, r, 61 FieldAccess access = {
61 kind}; 62 kTaggedBase, PropertyCell::kValueOffset, name, map, type, r, kind};
62 return access; 63 return access;
63 } 64 }
64 } // namespace 65 } // namespace
65 66
66 Reduction JSGlobalObjectSpecialization::ReduceJSLoadGlobal(Node* node) { 67 Reduction JSGlobalObjectSpecialization::ReduceJSLoadGlobal(Node* node) {
67 DCHECK_EQ(IrOpcode::kJSLoadGlobal, node->opcode()); 68 DCHECK_EQ(IrOpcode::kJSLoadGlobal, node->opcode());
68 Handle<Name> name = LoadGlobalParametersOf(node->op()).name(); 69 Handle<Name> name = LoadGlobalParametersOf(node->op()).name();
69 Node* effect = NodeProperties::GetEffectInput(node); 70 Node* effect = NodeProperties::GetEffectInput(node);
70 Node* control = NodeProperties::GetControlInput(node); 71 Node* control = NodeProperties::GetControlInput(node);
71 72
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
108 109
109 // Load from constant/undefined global property can be constant-folded. 110 // Load from constant/undefined global property can be constant-folded.
110 if (property_details.cell_type() == PropertyCellType::kConstant || 111 if (property_details.cell_type() == PropertyCellType::kConstant ||
111 property_details.cell_type() == PropertyCellType::kUndefined) { 112 property_details.cell_type() == PropertyCellType::kUndefined) {
112 Node* value = jsgraph()->Constant(property_cell_value); 113 Node* value = jsgraph()->Constant(property_cell_value);
113 ReplaceWithValue(node, value); 114 ReplaceWithValue(node, value);
114 return Replace(value); 115 return Replace(value);
115 } 116 }
116 117
117 // Load from constant type cell can benefit from type feedback. 118 // Load from constant type cell can benefit from type feedback.
119 MaybeHandle<Map> map;
118 Type* property_cell_value_type = Type::NonInternal(); 120 Type* property_cell_value_type = Type::NonInternal();
119 MachineRepresentation representation = MachineRepresentation::kTagged; 121 MachineRepresentation representation = MachineRepresentation::kTagged;
120 if (property_details.cell_type() == PropertyCellType::kConstantType) { 122 if (property_details.cell_type() == PropertyCellType::kConstantType) {
121 // Compute proper type based on the current value in the cell. 123 // Compute proper type based on the current value in the cell.
122 if (property_cell_value->IsSmi()) { 124 if (property_cell_value->IsSmi()) {
123 property_cell_value_type = Type::SignedSmall(); 125 property_cell_value_type = Type::SignedSmall();
124 representation = MachineRepresentation::kTaggedSigned; 126 representation = MachineRepresentation::kTaggedSigned;
125 } else if (property_cell_value->IsNumber()) { 127 } else if (property_cell_value->IsNumber()) {
126 property_cell_value_type = Type::Number(); 128 property_cell_value_type = Type::Number();
127 representation = MachineRepresentation::kTaggedPointer; 129 representation = MachineRepresentation::kTaggedPointer;
128 } else { 130 } else {
129 // TODO(turbofan): Track the property_cell_value_map on the FieldAccess
130 // below and use it in LoadElimination to eliminate map checks.
131 Handle<Map> property_cell_value_map( 131 Handle<Map> property_cell_value_map(
132 Handle<HeapObject>::cast(property_cell_value)->map(), isolate()); 132 Handle<HeapObject>::cast(property_cell_value)->map(), isolate());
133 property_cell_value_type = Type::For(property_cell_value_map); 133 property_cell_value_type = Type::For(property_cell_value_map);
134 representation = MachineRepresentation::kTaggedPointer; 134 representation = MachineRepresentation::kTaggedPointer;
135
136 // We can only use the property cell value map for map check elimination
137 // if it's stable, i.e. the HeapObject wasn't mutated without the cell
138 // state being updated.
139 if (property_cell_value_map->is_stable()) {
140 dependencies()->AssumeMapStable(property_cell_value_map);
141 map = property_cell_value_map;
142 }
135 } 143 }
136 } 144 }
137 Node* value = effect = 145 Node* value = effect = graph()->NewNode(
138 graph()->NewNode(simplified()->LoadField(ForPropertyCellValue( 146 simplified()->LoadField(ForPropertyCellValue(
139 representation, property_cell_value_type, name)), 147 representation, property_cell_value_type, map, name)),
140 jsgraph()->HeapConstant(property_cell), effect, control); 148 jsgraph()->HeapConstant(property_cell), effect, control);
141 ReplaceWithValue(node, value, effect, control); 149 ReplaceWithValue(node, value, effect, control);
142 return Replace(value); 150 return Replace(value);
143 } 151 }
144 152
145 153
146 Reduction JSGlobalObjectSpecialization::ReduceJSStoreGlobal(Node* node) { 154 Reduction JSGlobalObjectSpecialization::ReduceJSStoreGlobal(Node* node) {
147 DCHECK_EQ(IrOpcode::kJSStoreGlobal, node->opcode()); 155 DCHECK_EQ(IrOpcode::kJSStoreGlobal, node->opcode());
148 Handle<Name> name = StoreGlobalParametersOf(node->op()).name(); 156 Handle<Name> name = StoreGlobalParametersOf(node->op()).name();
149 Node* value = NodeProperties::GetValueInput(node, 0); 157 Node* value = NodeProperties::GetValueInput(node, 0);
150 Node* effect = NodeProperties::GetEffectInput(node); 158 Node* effect = NodeProperties::GetEffectInput(node);
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
211 value, effect, control); 219 value, effect, control);
212 property_cell_value_type = Type::OtherInternal(); 220 property_cell_value_type = Type::OtherInternal();
213 representation = MachineRepresentation::kTaggedPointer; 221 representation = MachineRepresentation::kTaggedPointer;
214 } else { 222 } else {
215 // Check that the {value} is a Smi. 223 // Check that the {value} is a Smi.
216 value = effect = 224 value = effect =
217 graph()->NewNode(simplified()->CheckSmi(), value, effect, control); 225 graph()->NewNode(simplified()->CheckSmi(), value, effect, control);
218 property_cell_value_type = Type::SignedSmall(); 226 property_cell_value_type = Type::SignedSmall();
219 representation = MachineRepresentation::kTaggedSigned; 227 representation = MachineRepresentation::kTaggedSigned;
220 } 228 }
221 effect = graph()->NewNode( 229 effect = graph()->NewNode(simplified()->StoreField(ForPropertyCellValue(
222 simplified()->StoreField(ForPropertyCellValue( 230 representation, property_cell_value_type,
223 representation, property_cell_value_type, name)), 231 MaybeHandle<Map>(), name)),
224 jsgraph()->HeapConstant(property_cell), value, effect, control); 232 jsgraph()->HeapConstant(property_cell), value,
233 effect, control);
225 break; 234 break;
226 } 235 }
227 case PropertyCellType::kMutable: { 236 case PropertyCellType::kMutable: {
228 // Record a code dependency on the cell, and just deoptimize if the 237 // Record a code dependency on the cell, and just deoptimize if the
229 // property ever becomes read-only. 238 // property ever becomes read-only.
230 dependencies()->AssumePropertyCell(property_cell); 239 dependencies()->AssumePropertyCell(property_cell);
231 effect = graph()->NewNode( 240 effect = graph()->NewNode(
232 simplified()->StoreField(ForPropertyCellValue( 241 simplified()->StoreField(ForPropertyCellValue(
233 MachineRepresentation::kTagged, Type::NonInternal(), name)), 242 MachineRepresentation::kTagged, Type::NonInternal(),
243 MaybeHandle<Map>(), name)),
234 jsgraph()->HeapConstant(property_cell), value, effect, control); 244 jsgraph()->HeapConstant(property_cell), value, effect, control);
235 break; 245 break;
236 } 246 }
237 } 247 }
238 ReplaceWithValue(node, value, effect, control); 248 ReplaceWithValue(node, value, effect, control);
239 return Replace(value); 249 return Replace(value);
240 } 250 }
241 251
242 bool JSGlobalObjectSpecialization::LookupInScriptContextTable( 252 bool JSGlobalObjectSpecialization::LookupInScriptContextTable(
243 Handle<Name> name, ScriptContextTableLookupResult* result) { 253 Handle<Name> name, ScriptContextTableLookupResult* result) {
(...skipping 29 matching lines...) Expand all
273 return jsgraph()->javascript(); 283 return jsgraph()->javascript();
274 } 284 }
275 285
276 SimplifiedOperatorBuilder* JSGlobalObjectSpecialization::simplified() const { 286 SimplifiedOperatorBuilder* JSGlobalObjectSpecialization::simplified() const {
277 return jsgraph()->simplified(); 287 return jsgraph()->simplified();
278 } 288 }
279 289
280 } // namespace compiler 290 } // namespace compiler
281 } // namespace internal 291 } // namespace internal
282 } // namespace v8 292 } // namespace v8
OLDNEW
« no previous file with comments | « src/compiler/js-create-lowering.cc ('k') | src/compiler/js-native-context-specialization.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698