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-native-context-specialization.h" | 5 #include "src/compiler/js-native-context-specialization.h" |
6 | 6 |
7 #include "src/accessors.h" | 7 #include "src/accessors.h" |
8 #include "src/code-factory.h" | 8 #include "src/code-factory.h" |
9 #include "src/compilation-dependencies.h" | 9 #include "src/compilation-dependencies.h" |
10 #include "src/compiler/access-builder.h" | 10 #include "src/compiler/access-builder.h" |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
48 template <typename T> | 48 template <typename T> |
49 bool HasOnlyStringMaps(T const& maps) { | 49 bool HasOnlyStringMaps(T const& maps) { |
50 for (auto map : maps) { | 50 for (auto map : maps) { |
51 if (!map->IsStringMap()) return false; | 51 if (!map->IsStringMap()) return false; |
52 } | 52 } |
53 return true; | 53 return true; |
54 } | 54 } |
55 | 55 |
56 } // namespace | 56 } // namespace |
57 | 57 |
58 struct JSNativeContextSpecialization::ScriptContextTableLookupResult { | |
59 Handle<Context> context; | |
60 bool immutable; | |
61 int index; | |
62 }; | |
63 | |
58 JSNativeContextSpecialization::JSNativeContextSpecialization( | 64 JSNativeContextSpecialization::JSNativeContextSpecialization( |
59 Editor* editor, JSGraph* jsgraph, Flags flags, | 65 Editor* editor, JSGraph* jsgraph, Flags flags, |
60 Handle<Context> native_context, CompilationDependencies* dependencies, | 66 Handle<Context> native_context, CompilationDependencies* dependencies, |
61 Zone* zone) | 67 Zone* zone) |
62 : AdvancedReducer(editor), | 68 : AdvancedReducer(editor), |
63 jsgraph_(jsgraph), | 69 jsgraph_(jsgraph), |
64 flags_(flags), | 70 flags_(flags), |
71 global_object_(native_context->global_object()), | |
72 global_proxy_(JSGlobalProxy::cast(native_context->global_proxy())), | |
65 native_context_(native_context), | 73 native_context_(native_context), |
66 dependencies_(dependencies), | 74 dependencies_(dependencies), |
67 zone_(zone), | 75 zone_(zone), |
68 type_cache_(TypeCache::Get()) {} | 76 type_cache_(TypeCache::Get()) {} |
69 | 77 |
70 Reduction JSNativeContextSpecialization::Reduce(Node* node) { | 78 Reduction JSNativeContextSpecialization::Reduce(Node* node) { |
71 switch (node->opcode()) { | 79 switch (node->opcode()) { |
72 case IrOpcode::kJSGetSuperConstructor: | 80 case IrOpcode::kJSGetSuperConstructor: |
73 return ReduceJSGetSuperConstructor(node); | 81 return ReduceJSGetSuperConstructor(node); |
74 case IrOpcode::kJSInstanceOf: | 82 case IrOpcode::kJSInstanceOf: |
75 return ReduceJSInstanceOf(node); | 83 return ReduceJSInstanceOf(node); |
76 case IrOpcode::kJSOrdinaryHasInstance: | 84 case IrOpcode::kJSOrdinaryHasInstance: |
77 return ReduceJSOrdinaryHasInstance(node); | 85 return ReduceJSOrdinaryHasInstance(node); |
78 case IrOpcode::kJSLoadContext: | 86 case IrOpcode::kJSLoadContext: |
79 return ReduceJSLoadContext(node); | 87 return ReduceJSLoadContext(node); |
88 case IrOpcode::kJSLoadGlobal: | |
89 return ReduceJSLoadGlobal(node); | |
90 case IrOpcode::kJSStoreGlobal: | |
91 return ReduceJSStoreGlobal(node); | |
80 case IrOpcode::kJSLoadNamed: | 92 case IrOpcode::kJSLoadNamed: |
81 return ReduceJSLoadNamed(node); | 93 return ReduceJSLoadNamed(node); |
82 case IrOpcode::kJSStoreNamed: | 94 case IrOpcode::kJSStoreNamed: |
83 return ReduceJSStoreNamed(node); | 95 return ReduceJSStoreNamed(node); |
84 case IrOpcode::kJSLoadProperty: | 96 case IrOpcode::kJSLoadProperty: |
85 return ReduceJSLoadProperty(node); | 97 return ReduceJSLoadProperty(node); |
86 case IrOpcode::kJSStoreProperty: | 98 case IrOpcode::kJSStoreProperty: |
87 return ReduceJSStoreProperty(node); | 99 return ReduceJSStoreProperty(node); |
88 case IrOpcode::kJSStoreDataPropertyInLiteral: | 100 case IrOpcode::kJSStoreDataPropertyInLiteral: |
89 return ReduceJSStoreDataPropertyInLiteral(node); | 101 return ReduceJSStoreDataPropertyInLiteral(node); |
(...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
248 // context (if any), so we can constant-fold those fields, which is | 260 // context (if any), so we can constant-fold those fields, which is |
249 // safe, since the NATIVE_CONTEXT_INDEX slot is always immutable. | 261 // safe, since the NATIVE_CONTEXT_INDEX slot is always immutable. |
250 if (access.index() == Context::NATIVE_CONTEXT_INDEX) { | 262 if (access.index() == Context::NATIVE_CONTEXT_INDEX) { |
251 Node* value = jsgraph()->HeapConstant(native_context()); | 263 Node* value = jsgraph()->HeapConstant(native_context()); |
252 ReplaceWithValue(node, value); | 264 ReplaceWithValue(node, value); |
253 return Replace(value); | 265 return Replace(value); |
254 } | 266 } |
255 return NoChange(); | 267 return NoChange(); |
256 } | 268 } |
257 | 269 |
270 namespace { | |
271 | |
272 FieldAccess ForPropertyCellValue(MachineRepresentation representation, | |
273 Type* type, MaybeHandle<Map> map, | |
274 Handle<Name> name) { | |
275 WriteBarrierKind kind = kFullWriteBarrier; | |
276 if (representation == MachineRepresentation::kTaggedSigned) { | |
277 kind = kNoWriteBarrier; | |
278 } else if (representation == MachineRepresentation::kTaggedPointer) { | |
279 kind = kPointerWriteBarrier; | |
280 } | |
281 MachineType r = MachineType::TypeForRepresentation(representation); | |
282 FieldAccess access = { | |
283 kTaggedBase, PropertyCell::kValueOffset, name, map, type, r, kind}; | |
284 return access; | |
285 } | |
286 | |
287 } // namespace | |
288 | |
289 Reduction JSNativeContextSpecialization::ReduceGlobalAccess( | |
290 Node* node, Node* receiver, Node* value, Handle<Name> name, | |
291 AccessMode access_mode) { | |
292 Node* effect = NodeProperties::GetEffectInput(node); | |
293 Node* control = NodeProperties::GetControlInput(node); | |
294 | |
295 // Lookup on the global object. We only deal with own data properties | |
296 // of the global object here (represented as PropertyCell). | |
297 LookupIterator it(global_object(), name, LookupIterator::OWN); | |
298 it.TryLookupCachedProperty(); | |
299 if (it.state() != LookupIterator::DATA) return NoChange(); | |
300 if (!it.GetHolder<JSObject>()->IsJSGlobalObject()) return NoChange(); | |
301 Handle<PropertyCell> property_cell = it.GetPropertyCell(); | |
302 PropertyDetails property_details = property_cell->property_details(); | |
303 Handle<Object> property_cell_value(property_cell->value(), isolate()); | |
304 PropertyCellType property_cell_type = property_details.cell_type(); | |
305 | |
306 // We have additional constraints for stores. | |
307 if (access_mode == AccessMode::kStore) { | |
308 if (property_details.IsReadOnly()) { | |
309 // Don't even bother trying to lower stores to read-only data properties. | |
310 return NoChange(); | |
311 } else if (property_cell_type == PropertyCellType::kUndefined) { | |
312 // There's no fast-path for dealing with undefined property cells. | |
313 return NoChange(); | |
314 } else if (property_cell_type == PropertyCellType::kConstantType) { | |
315 // There's also no fast-path to store to a global cell which pretended | |
316 // to be stable, but is no longer stable now. | |
317 if (property_cell_value->IsHeapObject() && | |
318 !Handle<HeapObject>::cast(property_cell_value)->map()->is_stable()) { | |
319 return NoChange(); | |
320 } | |
321 } | |
322 } | |
323 | |
324 // Check if we have a {receiver} to validate. If so, we need to check that | |
325 // the {receiver} is actually the JSGlobalProxy for the native context that | |
326 // we are specializing to. | |
327 if (receiver != nullptr) { | |
328 Node* check = graph()->NewNode(simplified()->ReferenceEqual(), receiver, | |
329 jsgraph()->HeapConstant(global_proxy())); | |
330 effect = graph()->NewNode(simplified()->CheckIf(), check, effect, control); | |
331 } | |
332 | |
333 if (access_mode == AccessMode::kLoad) { | |
334 // Load from non-configurable, read-only data property on the global | |
335 // object can be constant-folded, even without deoptimization support. | |
336 if (!property_details.IsConfigurable() && property_details.IsReadOnly()) { | |
337 value = jsgraph()->Constant(property_cell_value); | |
338 } else { | |
339 // Record a code dependency on the cell if we can benefit from the | |
340 // additional feedback, or the global property is configurable (i.e. | |
341 // can be deleted or reconfigured to an accessor property). | |
342 if (property_details.cell_type() != PropertyCellType::kMutable || | |
343 property_details.IsConfigurable()) { | |
344 dependencies()->AssumePropertyCell(property_cell); | |
345 } | |
346 | |
347 // Load from constant/undefined global property can be constant-folded. | |
348 if (property_details.cell_type() == PropertyCellType::kConstant || | |
349 property_details.cell_type() == PropertyCellType::kUndefined) { | |
350 value = jsgraph()->Constant(property_cell_value); | |
351 } else { | |
352 // Load from constant type cell can benefit from type feedback. | |
353 MaybeHandle<Map> map; | |
354 Type* property_cell_value_type = Type::NonInternal(); | |
355 MachineRepresentation representation = MachineRepresentation::kTagged; | |
356 if (property_details.cell_type() == PropertyCellType::kConstantType) { | |
357 // Compute proper type based on the current value in the cell. | |
358 if (property_cell_value->IsSmi()) { | |
359 property_cell_value_type = Type::SignedSmall(); | |
360 representation = MachineRepresentation::kTaggedSigned; | |
361 } else if (property_cell_value->IsNumber()) { | |
362 property_cell_value_type = Type::Number(); | |
363 representation = MachineRepresentation::kTaggedPointer; | |
364 } else { | |
365 Handle<Map> property_cell_value_map( | |
366 Handle<HeapObject>::cast(property_cell_value)->map(), | |
367 isolate()); | |
368 property_cell_value_type = Type::For(property_cell_value_map); | |
369 representation = MachineRepresentation::kTaggedPointer; | |
370 | |
371 // We can only use the property cell value map for map check | |
372 // elimination if it's stable, i.e. the HeapObject wasn't | |
373 // mutated without the cell state being updated. | |
374 if (property_cell_value_map->is_stable()) { | |
375 dependencies()->AssumeMapStable(property_cell_value_map); | |
376 map = property_cell_value_map; | |
377 } | |
378 } | |
379 } | |
380 value = effect = graph()->NewNode( | |
381 simplified()->LoadField(ForPropertyCellValue( | |
382 representation, property_cell_value_type, map, name)), | |
383 jsgraph()->HeapConstant(property_cell), effect, control); | |
384 } | |
385 } | |
386 } else { | |
387 DCHECK_EQ(AccessMode::kStore, access_mode); | |
388 DCHECK(!property_details.IsReadOnly()); | |
389 switch (property_details.cell_type()) { | |
390 case PropertyCellType::kUndefined: { | |
391 UNREACHABLE(); | |
392 break; | |
393 } | |
394 case PropertyCellType::kConstant: { | |
395 // Record a code dependency on the cell, and just deoptimize if the new | |
396 // value doesn't match the previous value stored inside the cell. | |
397 dependencies()->AssumePropertyCell(property_cell); | |
398 Node* check = | |
399 graph()->NewNode(simplified()->ReferenceEqual(), value, | |
400 jsgraph()->Constant(property_cell_value)); | |
401 effect = | |
402 graph()->NewNode(simplified()->CheckIf(), check, effect, control); | |
403 break; | |
404 } | |
405 case PropertyCellType::kConstantType: { | |
406 // Record a code dependency on the cell, and just deoptimize if the new | |
407 // values' type doesn't match the type of the previous value in the | |
408 // cell. | |
409 dependencies()->AssumePropertyCell(property_cell); | |
410 Type* property_cell_value_type; | |
411 MachineRepresentation representation = MachineRepresentation::kTagged; | |
412 if (property_cell_value->IsHeapObject()) { | |
413 // We cannot do anything if the {property_cell_value}s map is no | |
414 // longer stable. | |
415 Handle<Map> property_cell_value_map( | |
416 Handle<HeapObject>::cast(property_cell_value)->map(), isolate()); | |
417 DCHECK(!property_cell_value_map->is_stable()); | |
418 dependencies()->AssumeMapStable(property_cell_value_map); | |
419 | |
420 // Check that the {value} is a HeapObject. | |
421 value = effect = graph()->NewNode(simplified()->CheckHeapObject(), | |
422 value, effect, control); | |
423 | |
424 // Check {value} map agains the {property_cell} map. | |
425 effect = | |
426 graph()->NewNode(simplified()->CheckMaps( | |
427 CheckMapsFlag::kNone, | |
428 ZoneHandleSet<Map>(property_cell_value_map)), | |
429 value, effect, control); | |
430 property_cell_value_type = Type::OtherInternal(); | |
431 representation = MachineRepresentation::kTaggedPointer; | |
432 } else { | |
433 // Check that the {value} is a Smi. | |
434 value = effect = graph()->NewNode(simplified()->CheckSmi(), value, | |
435 effect, control); | |
436 property_cell_value_type = Type::SignedSmall(); | |
437 representation = MachineRepresentation::kTaggedSigned; | |
438 } | |
439 effect = graph()->NewNode(simplified()->StoreField(ForPropertyCellValue( | |
440 representation, property_cell_value_type, | |
441 MaybeHandle<Map>(), name)), | |
442 jsgraph()->HeapConstant(property_cell), value, | |
443 effect, control); | |
444 break; | |
445 } | |
446 case PropertyCellType::kMutable: { | |
447 // Record a code dependency on the cell, and just deoptimize if the | |
448 // property ever becomes read-only. | |
449 dependencies()->AssumePropertyCell(property_cell); | |
450 effect = graph()->NewNode( | |
451 simplified()->StoreField(ForPropertyCellValue( | |
452 MachineRepresentation::kTagged, Type::NonInternal(), | |
453 MaybeHandle<Map>(), name)), | |
454 jsgraph()->HeapConstant(property_cell), value, effect, control); | |
455 break; | |
456 } | |
457 } | |
458 } | |
459 | |
460 ReplaceWithValue(node, value, effect, control); | |
461 return Replace(value); | |
462 } | |
463 | |
464 Reduction JSNativeContextSpecialization::ReduceJSLoadGlobal(Node* node) { | |
465 DCHECK_EQ(IrOpcode::kJSLoadGlobal, node->opcode()); | |
466 Handle<Name> name = LoadGlobalParametersOf(node->op()).name(); | |
467 Node* effect = NodeProperties::GetEffectInput(node); | |
468 Node* control = NodeProperties::GetControlInput(node); | |
469 | |
470 // Try to lookup the name on the script context table first (lexical scoping). | |
471 ScriptContextTableLookupResult result; | |
472 if (LookupInScriptContextTable(name, &result)) { | |
473 if (result.context->is_the_hole(isolate(), result.index)) return NoChange(); | |
474 Node* context = jsgraph()->HeapConstant(result.context); | |
475 Node* value = effect = graph()->NewNode( | |
476 javascript()->LoadContext(0, result.index, result.immutable), context, | |
477 effect); | |
478 ReplaceWithValue(node, value, effect); | |
479 return Replace(value); | |
480 } | |
481 | |
482 // Not much we can do if deoptimization support is disabled. | |
483 if (!(flags() & kDeoptimizationEnabled)) return NoChange(); | |
484 | |
485 // Lookup the {name} on the global object instead. | |
486 return ReduceGlobalAccess(node, nullptr, nullptr, name, AccessMode::kLoad); | |
487 } | |
488 | |
489 Reduction JSNativeContextSpecialization::ReduceJSStoreGlobal(Node* node) { | |
490 DCHECK_EQ(IrOpcode::kJSStoreGlobal, node->opcode()); | |
491 Handle<Name> name = StoreGlobalParametersOf(node->op()).name(); | |
492 Node* value = NodeProperties::GetValueInput(node, 0); | |
493 Node* effect = NodeProperties::GetEffectInput(node); | |
494 Node* control = NodeProperties::GetControlInput(node); | |
495 | |
496 // Try to lookup the name on the script context table first (lexical scoping). | |
497 ScriptContextTableLookupResult result; | |
498 if (LookupInScriptContextTable(name, &result)) { | |
499 if (result.context->is_the_hole(isolate(), result.index)) return NoChange(); | |
500 if (result.immutable) return NoChange(); | |
501 Node* context = jsgraph()->HeapConstant(result.context); | |
502 effect = graph()->NewNode(javascript()->StoreContext(0, result.index), | |
503 value, context, effect, control); | |
504 ReplaceWithValue(node, value, effect, control); | |
505 return Replace(value); | |
506 } | |
507 | |
508 // Not much we can do if deoptimization support is disabled. | |
509 if (!(flags() & kDeoptimizationEnabled)) return NoChange(); | |
510 | |
511 // Lookup the {name} on the global object instead. | |
512 return ReduceGlobalAccess(node, nullptr, value, name, AccessMode::kStore); | |
513 } | |
514 | |
258 Reduction JSNativeContextSpecialization::ReduceNamedAccess( | 515 Reduction JSNativeContextSpecialization::ReduceNamedAccess( |
259 Node* node, Node* value, MapHandleList const& receiver_maps, | 516 Node* node, Node* value, MapHandleList const& receiver_maps, |
260 Handle<Name> name, AccessMode access_mode, LanguageMode language_mode, | 517 Handle<Name> name, AccessMode access_mode, LanguageMode language_mode, |
261 Handle<TypeFeedbackVector> vector, FeedbackVectorSlot slot, Node* index) { | 518 Handle<TypeFeedbackVector> vector, FeedbackVectorSlot slot, Node* index) { |
262 DCHECK(node->opcode() == IrOpcode::kJSLoadNamed || | 519 DCHECK(node->opcode() == IrOpcode::kJSLoadNamed || |
263 node->opcode() == IrOpcode::kJSStoreNamed || | 520 node->opcode() == IrOpcode::kJSStoreNamed || |
264 node->opcode() == IrOpcode::kJSLoadProperty || | 521 node->opcode() == IrOpcode::kJSLoadProperty || |
265 node->opcode() == IrOpcode::kJSStoreProperty); | 522 node->opcode() == IrOpcode::kJSStoreProperty); |
266 Node* receiver = NodeProperties::GetValueInput(node, 0); | 523 Node* receiver = NodeProperties::GetValueInput(node, 0); |
267 Node* context = NodeProperties::GetContextInput(node); | 524 Node* context = NodeProperties::GetContextInput(node); |
268 Node* frame_state_eager = NodeProperties::FindFrameStateBefore(node); | 525 Node* frame_state_eager = NodeProperties::FindFrameStateBefore(node); |
269 Node* frame_state_lazy = NodeProperties::GetFrameStateInput(node); | 526 Node* frame_state_lazy = NodeProperties::GetFrameStateInput(node); |
270 Node* effect = NodeProperties::GetEffectInput(node); | 527 Node* effect = NodeProperties::GetEffectInput(node); |
271 Node* control = NodeProperties::GetControlInput(node); | 528 Node* control = NodeProperties::GetControlInput(node); |
272 | 529 |
273 // Not much we can do if deoptimization support is disabled. | 530 // Not much we can do if deoptimization support is disabled. |
274 if (!(flags() & kDeoptimizationEnabled)) return NoChange(); | 531 if (!(flags() & kDeoptimizationEnabled)) return NoChange(); |
275 | 532 |
533 // Check if we have an access o.x or o.x=v where o is the current | |
534 // native contexts' global proxy, and turn that into a direct access | |
535 // to the current native contexts' global object instead. | |
536 if (receiver_maps.length() == 1) { | |
Benedikt Meurer
2017/01/30 18:11:18
This is part one of the new stuff.
| |
537 Handle<Map> receiver_map = receiver_maps.first(); | |
538 if (receiver_map->IsJSGlobalProxyMap()) { | |
539 Handle<JSFunction> receiver_constructor = | |
540 handle(JSFunction::cast(receiver_map->GetConstructor()), isolate()); | |
541 if (receiver_constructor->native_context() == *native_context()) { | |
542 return ReduceGlobalAccess(node, receiver, value, name, access_mode); | |
543 } | |
544 } | |
545 } | |
546 | |
276 // Compute property access infos for the receiver maps. | 547 // Compute property access infos for the receiver maps. |
277 AccessInfoFactory access_info_factory(dependencies(), native_context(), | 548 AccessInfoFactory access_info_factory(dependencies(), native_context(), |
278 graph()->zone()); | 549 graph()->zone()); |
279 ZoneVector<PropertyAccessInfo> access_infos(zone()); | 550 ZoneVector<PropertyAccessInfo> access_infos(zone()); |
280 if (!access_info_factory.ComputePropertyAccessInfos( | 551 if (!access_info_factory.ComputePropertyAccessInfos( |
281 receiver_maps, name, access_mode, &access_infos)) { | 552 receiver_maps, name, access_mode, &access_infos)) { |
282 return NoChange(); | 553 return NoChange(); |
283 } | 554 } |
284 | 555 |
285 // TODO(turbofan): Add support for inlining into try blocks. | 556 // TODO(turbofan): Add support for inlining into try blocks. |
(...skipping 194 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
480 } | 751 } |
481 | 752 |
482 Reduction JSNativeContextSpecialization::ReduceNamedAccessFromNexus( | 753 Reduction JSNativeContextSpecialization::ReduceNamedAccessFromNexus( |
483 Node* node, Node* value, FeedbackNexus const& nexus, Handle<Name> name, | 754 Node* node, Node* value, FeedbackNexus const& nexus, Handle<Name> name, |
484 AccessMode access_mode, LanguageMode language_mode) { | 755 AccessMode access_mode, LanguageMode language_mode) { |
485 DCHECK(node->opcode() == IrOpcode::kJSLoadNamed || | 756 DCHECK(node->opcode() == IrOpcode::kJSLoadNamed || |
486 node->opcode() == IrOpcode::kJSStoreNamed); | 757 node->opcode() == IrOpcode::kJSStoreNamed); |
487 Node* const receiver = NodeProperties::GetValueInput(node, 0); | 758 Node* const receiver = NodeProperties::GetValueInput(node, 0); |
488 Node* const effect = NodeProperties::GetEffectInput(node); | 759 Node* const effect = NodeProperties::GetEffectInput(node); |
489 | 760 |
761 // Check if we are accessing the current native contexts' global proxy. | |
Benedikt Meurer
2017/01/30 18:11:18
And this is part two of the new stuff.
| |
762 HeapObjectMatcher m(receiver); | |
763 if (m.HasValue() && m.Value().is_identical_to(global_proxy())) { | |
764 // Optimize accesses to the current native contexts' global proxy. | |
765 return ReduceGlobalAccess(node, nullptr, value, name, access_mode); | |
766 } | |
767 | |
490 // Check if the {nexus} reports type feedback for the IC. | 768 // Check if the {nexus} reports type feedback for the IC. |
491 if (nexus.IsUninitialized()) { | 769 if (nexus.IsUninitialized()) { |
492 if ((flags() & kDeoptimizationEnabled) && | 770 if ((flags() & kDeoptimizationEnabled) && |
493 (flags() & kBailoutOnUninitialized)) { | 771 (flags() & kBailoutOnUninitialized)) { |
494 return ReduceSoftDeoptimize( | 772 return ReduceSoftDeoptimize( |
495 node, | 773 node, |
496 DeoptimizeReason::kInsufficientTypeFeedbackForGenericNamedAccess); | 774 DeoptimizeReason::kInsufficientTypeFeedbackForGenericNamedAccess); |
497 } | 775 } |
498 return NoChange(); | 776 return NoChange(); |
499 } | 777 } |
(...skipping 10 matching lines...) Expand all Loading... | |
510 DeoptimizeReason::kInsufficientTypeFeedbackForGenericNamedAccess); | 788 DeoptimizeReason::kInsufficientTypeFeedbackForGenericNamedAccess); |
511 } | 789 } |
512 return NoChange(); | 790 return NoChange(); |
513 } | 791 } |
514 | 792 |
515 // Try to lower the named access based on the {receiver_maps}. | 793 // Try to lower the named access based on the {receiver_maps}. |
516 return ReduceNamedAccess(node, value, receiver_maps, name, access_mode, | 794 return ReduceNamedAccess(node, value, receiver_maps, name, access_mode, |
517 language_mode, nexus.vector_handle(), nexus.slot()); | 795 language_mode, nexus.vector_handle(), nexus.slot()); |
518 } | 796 } |
519 | 797 |
520 | |
521 Reduction JSNativeContextSpecialization::ReduceJSLoadNamed(Node* node) { | 798 Reduction JSNativeContextSpecialization::ReduceJSLoadNamed(Node* node) { |
522 DCHECK_EQ(IrOpcode::kJSLoadNamed, node->opcode()); | 799 DCHECK_EQ(IrOpcode::kJSLoadNamed, node->opcode()); |
523 NamedAccess const& p = NamedAccessOf(node->op()); | 800 NamedAccess const& p = NamedAccessOf(node->op()); |
524 Node* const receiver = NodeProperties::GetValueInput(node, 0); | 801 Node* const receiver = NodeProperties::GetValueInput(node, 0); |
525 Node* const value = jsgraph()->Dead(); | 802 Node* const value = jsgraph()->Dead(); |
526 | 803 |
527 // Check if we have a constant receiver. | 804 // Check if we have a constant receiver. |
528 HeapObjectMatcher m(receiver); | 805 HeapObjectMatcher m(receiver); |
529 if (m.HasValue()) { | 806 if (m.HasValue()) { |
530 if (m.Value()->IsJSFunction() && | 807 if (m.Value()->IsJSFunction() && |
(...skipping 30 matching lines...) Expand all Loading... | |
561 | 838 |
562 // Try to lower the named access based on the {receiver_maps}. | 839 // Try to lower the named access based on the {receiver_maps}. |
563 return ReduceNamedAccessFromNexus(node, value, nexus, p.name(), | 840 return ReduceNamedAccessFromNexus(node, value, nexus, p.name(), |
564 AccessMode::kLoad, p.language_mode()); | 841 AccessMode::kLoad, p.language_mode()); |
565 } | 842 } |
566 | 843 |
567 | 844 |
568 Reduction JSNativeContextSpecialization::ReduceJSStoreNamed(Node* node) { | 845 Reduction JSNativeContextSpecialization::ReduceJSStoreNamed(Node* node) { |
569 DCHECK_EQ(IrOpcode::kJSStoreNamed, node->opcode()); | 846 DCHECK_EQ(IrOpcode::kJSStoreNamed, node->opcode()); |
570 NamedAccess const& p = NamedAccessOf(node->op()); | 847 NamedAccess const& p = NamedAccessOf(node->op()); |
848 Node* const receiver = NodeProperties::GetValueInput(node, 0); | |
571 Node* const value = NodeProperties::GetValueInput(node, 1); | 849 Node* const value = NodeProperties::GetValueInput(node, 1); |
572 | 850 |
573 // Extract receiver maps from the STORE_IC using the StoreICNexus. | 851 // Extract receiver maps from the STORE_IC using the StoreICNexus. |
574 if (!p.feedback().IsValid()) return NoChange(); | 852 if (!p.feedback().IsValid()) return NoChange(); |
575 StoreICNexus nexus(p.feedback().vector(), p.feedback().slot()); | 853 StoreICNexus nexus(p.feedback().vector(), p.feedback().slot()); |
576 | 854 |
577 // Try to lower the named access based on the {receiver_maps}. | 855 // Try to lower the named access based on the {receiver_maps}. |
578 return ReduceNamedAccessFromNexus(node, value, nexus, p.name(), | 856 return ReduceNamedAccessFromNexus(node, value, nexus, p.name(), |
579 AccessMode::kStore, p.language_mode()); | 857 AccessMode::kStore, p.language_mode()); |
580 } | 858 } |
(...skipping 1354 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1935 if (initial_map->constructor_or_backpointer() == *mnewtarget.Value()) { | 2213 if (initial_map->constructor_or_backpointer() == *mnewtarget.Value()) { |
1936 DCHECK_EQ(*initial_map, initial_map->FindRootMap()); | 2214 DCHECK_EQ(*initial_map, initial_map->FindRootMap()); |
1937 return initial_map; | 2215 return initial_map; |
1938 } | 2216 } |
1939 } | 2217 } |
1940 } | 2218 } |
1941 } | 2219 } |
1942 return MaybeHandle<Map>(); | 2220 return MaybeHandle<Map>(); |
1943 } | 2221 } |
1944 | 2222 |
2223 bool JSNativeContextSpecialization::LookupInScriptContextTable( | |
2224 Handle<Name> name, ScriptContextTableLookupResult* result) { | |
2225 if (!name->IsString()) return false; | |
2226 Handle<ScriptContextTable> script_context_table( | |
2227 global_object()->native_context()->script_context_table(), isolate()); | |
2228 ScriptContextTable::LookupResult lookup_result; | |
2229 if (!ScriptContextTable::Lookup(script_context_table, | |
2230 Handle<String>::cast(name), &lookup_result)) { | |
2231 return false; | |
2232 } | |
2233 Handle<Context> script_context = ScriptContextTable::GetContext( | |
2234 script_context_table, lookup_result.context_index); | |
2235 result->context = script_context; | |
2236 result->immutable = lookup_result.mode == CONST; | |
2237 result->index = lookup_result.slot_index; | |
2238 return true; | |
2239 } | |
2240 | |
1945 Graph* JSNativeContextSpecialization::graph() const { | 2241 Graph* JSNativeContextSpecialization::graph() const { |
1946 return jsgraph()->graph(); | 2242 return jsgraph()->graph(); |
1947 } | 2243 } |
1948 | 2244 |
1949 Isolate* JSNativeContextSpecialization::isolate() const { | 2245 Isolate* JSNativeContextSpecialization::isolate() const { |
1950 return jsgraph()->isolate(); | 2246 return jsgraph()->isolate(); |
1951 } | 2247 } |
1952 | 2248 |
1953 Factory* JSNativeContextSpecialization::factory() const { | 2249 Factory* JSNativeContextSpecialization::factory() const { |
1954 return isolate()->factory(); | 2250 return isolate()->factory(); |
(...skipping 11 matching lines...) Expand all Loading... | |
1966 return jsgraph()->javascript(); | 2262 return jsgraph()->javascript(); |
1967 } | 2263 } |
1968 | 2264 |
1969 SimplifiedOperatorBuilder* JSNativeContextSpecialization::simplified() const { | 2265 SimplifiedOperatorBuilder* JSNativeContextSpecialization::simplified() const { |
1970 return jsgraph()->simplified(); | 2266 return jsgraph()->simplified(); |
1971 } | 2267 } |
1972 | 2268 |
1973 } // namespace compiler | 2269 } // namespace compiler |
1974 } // namespace internal | 2270 } // namespace internal |
1975 } // namespace v8 | 2271 } // namespace v8 |
OLD | NEW |