OLD | NEW |
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-type-feedback.h" | 5 #include "src/compiler/js-type-feedback.h" |
6 | 6 |
7 #include "src/property-details.h" | 7 #include "src/property-details.h" |
8 | 8 |
9 #include "src/accessors.h" | 9 #include "src/accessors.h" |
10 #include "src/ast.h" | 10 #include "src/ast.h" |
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
139 } | 139 } |
140 | 140 |
141 | 141 |
142 Reduction JSTypeFeedbackSpecializer::ReduceJSLoadNamed(Node* node) { | 142 Reduction JSTypeFeedbackSpecializer::ReduceJSLoadNamed(Node* node) { |
143 DCHECK(node->opcode() == IrOpcode::kJSLoadNamed); | 143 DCHECK(node->opcode() == IrOpcode::kJSLoadNamed); |
144 if (mode() != kDeoptimizationEnabled) return NoChange(); | 144 if (mode() != kDeoptimizationEnabled) return NoChange(); |
145 Node* frame_state_before = GetFrameStateBefore(node); | 145 Node* frame_state_before = GetFrameStateBefore(node); |
146 if (frame_state_before == nullptr) return NoChange(); | 146 if (frame_state_before == nullptr) return NoChange(); |
147 | 147 |
148 const LoadNamedParameters& p = LoadNamedParametersOf(node->op()); | 148 const LoadNamedParameters& p = LoadNamedParametersOf(node->op()); |
149 Handle<Name> name = p.name().handle(); | |
150 SmallMapList maps; | 149 SmallMapList maps; |
151 | 150 |
152 FeedbackVectorICSlot slot = js_type_feedback_->FindFeedbackVectorICSlot(node); | 151 FeedbackVectorICSlot slot = js_type_feedback_->FindFeedbackVectorICSlot(node); |
153 if (slot.IsInvalid() || | 152 if (slot.IsInvalid() || |
154 oracle()->LoadInlineCacheState(slot) == UNINITIALIZED) { | 153 oracle()->LoadInlineCacheState(slot) == UNINITIALIZED) { |
155 // No type feedback ids or the load is uninitialized. | 154 // No type feedback ids or the load is uninitialized. |
156 return NoChange(); | 155 return NoChange(); |
157 } | 156 } |
158 oracle()->PropertyReceiverTypes(slot, name, &maps); | 157 oracle()->PropertyReceiverTypes(slot, p.name(), &maps); |
159 | 158 |
160 Node* receiver = node->InputAt(0); | 159 Node* receiver = node->InputAt(0); |
161 Node* effect = NodeProperties::GetEffectInput(node); | 160 Node* effect = NodeProperties::GetEffectInput(node); |
162 | 161 |
163 if (maps.length() != 1) return NoChange(); // TODO(turbofan): polymorphism | 162 if (maps.length() != 1) return NoChange(); // TODO(turbofan): polymorphism |
164 if (!ENABLE_FAST_PROPERTY_LOADS) return NoChange(); | 163 if (!ENABLE_FAST_PROPERTY_LOADS) return NoChange(); |
165 | 164 |
166 Handle<Map> map = maps.first(); | 165 Handle<Map> map = maps.first(); |
167 FieldAccess field_access; | 166 FieldAccess field_access; |
168 if (!GetInObjectFieldAccess(LOAD, map, name, &field_access)) { | 167 if (!GetInObjectFieldAccess(LOAD, map, p.name(), &field_access)) { |
169 return NoChange(); | 168 return NoChange(); |
170 } | 169 } |
171 | 170 |
172 Node* control = NodeProperties::GetControlInput(node); | 171 Node* control = NodeProperties::GetControlInput(node); |
173 Node* check_success; | 172 Node* check_success; |
174 Node* check_failed; | 173 Node* check_failed; |
175 BuildMapCheck(receiver, map, true, effect, control, &check_success, | 174 BuildMapCheck(receiver, map, true, effect, control, &check_success, |
176 &check_failed); | 175 &check_failed); |
177 | 176 |
178 // Build the actual load. | 177 // Build the actual load. |
179 Node* load = graph()->NewNode(simplified()->LoadField(field_access), receiver, | 178 Node* load = graph()->NewNode(simplified()->LoadField(field_access), receiver, |
180 effect, check_success); | 179 effect, check_success); |
181 | 180 |
182 // TODO(turbofan): handle slow case instead of deoptimizing. | 181 // TODO(turbofan): handle slow case instead of deoptimizing. |
183 Node* deopt = graph()->NewNode(common()->Deoptimize(), frame_state_before, | 182 Node* deopt = graph()->NewNode(common()->Deoptimize(), frame_state_before, |
184 effect, check_failed); | 183 effect, check_failed); |
185 NodeProperties::MergeControlToEnd(graph(), common(), deopt); | 184 NodeProperties::MergeControlToEnd(graph(), common(), deopt); |
186 ReplaceWithValue(node, load, load, check_success); | 185 ReplaceWithValue(node, load, load, check_success); |
187 return Replace(load); | 186 return Replace(load); |
188 } | 187 } |
189 | 188 |
190 | 189 |
191 Reduction JSTypeFeedbackSpecializer::ReduceJSLoadGlobal(Node* node) { | 190 Reduction JSTypeFeedbackSpecializer::ReduceJSLoadGlobal(Node* node) { |
192 DCHECK(node->opcode() == IrOpcode::kJSLoadGlobal); | 191 DCHECK(node->opcode() == IrOpcode::kJSLoadGlobal); |
193 Handle<String> name = | 192 Handle<String> name = |
194 Handle<String>::cast(LoadGlobalParametersOf(node->op()).name().handle()); | 193 Handle<String>::cast(LoadGlobalParametersOf(node->op()).name()); |
195 // Try to optimize loads from the global object. | 194 // Try to optimize loads from the global object. |
196 Handle<Object> constant_value = | 195 Handle<Object> constant_value = |
197 jsgraph()->isolate()->factory()->GlobalConstantFor(name); | 196 jsgraph()->isolate()->factory()->GlobalConstantFor(name); |
198 if (!constant_value.is_null()) { | 197 if (!constant_value.is_null()) { |
199 // Always optimize global constants. | 198 // Always optimize global constants. |
200 Node* constant = jsgraph()->Constant(constant_value); | 199 Node* constant = jsgraph()->Constant(constant_value); |
201 ReplaceWithValue(node, constant); | 200 ReplaceWithValue(node, constant); |
202 return Replace(constant); | 201 return Replace(constant); |
203 } | 202 } |
204 | 203 |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
260 return NoChange(); | 259 return NoChange(); |
261 } | 260 } |
262 | 261 |
263 | 262 |
264 Reduction JSTypeFeedbackSpecializer::ReduceJSStoreNamed(Node* node) { | 263 Reduction JSTypeFeedbackSpecializer::ReduceJSStoreNamed(Node* node) { |
265 DCHECK(node->opcode() == IrOpcode::kJSStoreNamed); | 264 DCHECK(node->opcode() == IrOpcode::kJSStoreNamed); |
266 Node* frame_state_before = GetFrameStateBefore(node); | 265 Node* frame_state_before = GetFrameStateBefore(node); |
267 if (frame_state_before == nullptr) return NoChange(); | 266 if (frame_state_before == nullptr) return NoChange(); |
268 | 267 |
269 const StoreNamedParameters& p = StoreNamedParametersOf(node->op()); | 268 const StoreNamedParameters& p = StoreNamedParametersOf(node->op()); |
270 Handle<Name> name = p.name().handle(); | |
271 SmallMapList maps; | 269 SmallMapList maps; |
272 TypeFeedbackId id = js_type_feedback_->FindTypeFeedbackId(node); | 270 TypeFeedbackId id = js_type_feedback_->FindTypeFeedbackId(node); |
273 if (id.IsNone() || oracle()->StoreIsUninitialized(id) == UNINITIALIZED) { | 271 if (id.IsNone() || oracle()->StoreIsUninitialized(id) == UNINITIALIZED) { |
274 // No type feedback ids or the store is uninitialized. | 272 // No type feedback ids or the store is uninitialized. |
275 // TODO(titzer): no feedback from vector ICs from stores. | 273 // TODO(titzer): no feedback from vector ICs from stores. |
276 return NoChange(); | 274 return NoChange(); |
277 } else { | 275 } else { |
278 oracle()->AssignmentReceiverTypes(id, name, &maps); | 276 oracle()->AssignmentReceiverTypes(id, p.name(), &maps); |
279 } | 277 } |
280 | 278 |
281 Node* receiver = node->InputAt(0); | 279 Node* receiver = node->InputAt(0); |
282 Node* effect = NodeProperties::GetEffectInput(node); | 280 Node* effect = NodeProperties::GetEffectInput(node); |
283 | 281 |
284 if (maps.length() != 1) return NoChange(); // TODO(turbofan): polymorphism | 282 if (maps.length() != 1) return NoChange(); // TODO(turbofan): polymorphism |
285 | 283 |
286 if (!ENABLE_FAST_PROPERTY_STORES) return NoChange(); | 284 if (!ENABLE_FAST_PROPERTY_STORES) return NoChange(); |
287 | 285 |
288 Handle<Map> map = maps.first(); | 286 Handle<Map> map = maps.first(); |
289 FieldAccess field_access; | 287 FieldAccess field_access; |
290 if (!GetInObjectFieldAccess(STORE, map, name, &field_access)) { | 288 if (!GetInObjectFieldAccess(STORE, map, p.name(), &field_access)) { |
291 return NoChange(); | 289 return NoChange(); |
292 } | 290 } |
293 | 291 |
294 Node* control = NodeProperties::GetControlInput(node); | 292 Node* control = NodeProperties::GetControlInput(node); |
295 Node* check_success; | 293 Node* check_success; |
296 Node* check_failed; | 294 Node* check_failed; |
297 BuildMapCheck(receiver, map, true, effect, control, &check_success, | 295 BuildMapCheck(receiver, map, true, effect, control, &check_success, |
298 &check_failed); | 296 &check_failed); |
299 | 297 |
300 // Build the actual load. | 298 // Build the actual load. |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
357 BailoutId id = OpParameter<FrameStateInfo>(node).bailout_id(); | 355 BailoutId id = OpParameter<FrameStateInfo>(node).bailout_id(); |
358 if (id != BailoutId::None()) return frame_state; | 356 if (id != BailoutId::None()) return frame_state; |
359 } | 357 } |
360 } | 358 } |
361 return nullptr; | 359 return nullptr; |
362 } | 360 } |
363 | 361 |
364 } // namespace compiler | 362 } // namespace compiler |
365 } // namespace internal | 363 } // namespace internal |
366 } // namespace v8 | 364 } // namespace v8 |
OLD | NEW |