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( | |
Igor Sheludko
2017/01/30 23:09:33
Drive-by comment: the load and store cases are rat
Benedikt Meurer
2017/01/31 04:55:10
Acknowledged.
| |
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 | |
469 // Try to lookup the name on the script context table first (lexical scoping). | |
470 ScriptContextTableLookupResult result; | |
471 if (LookupInScriptContextTable(name, &result)) { | |
472 if (result.context->is_the_hole(isolate(), result.index)) return NoChange(); | |
473 Node* context = jsgraph()->HeapConstant(result.context); | |
474 Node* value = effect = graph()->NewNode( | |
475 javascript()->LoadContext(0, result.index, result.immutable), context, | |
476 effect); | |
477 ReplaceWithValue(node, value, effect); | |
478 return Replace(value); | |
479 } | |
480 | |
481 // Not much we can do if deoptimization support is disabled. | |
482 if (!(flags() & kDeoptimizationEnabled)) return NoChange(); | |
483 | |
484 // Lookup the {name} on the global object instead. | |
485 return ReduceGlobalAccess(node, nullptr, nullptr, name, AccessMode::kLoad); | |
486 } | |
487 | |
488 Reduction JSNativeContextSpecialization::ReduceJSStoreGlobal(Node* node) { | |
489 DCHECK_EQ(IrOpcode::kJSStoreGlobal, node->opcode()); | |
490 Handle<Name> name = StoreGlobalParametersOf(node->op()).name(); | |
491 Node* value = NodeProperties::GetValueInput(node, 0); | |
492 Node* effect = NodeProperties::GetEffectInput(node); | |
493 Node* control = NodeProperties::GetControlInput(node); | |
494 | |
495 // Try to lookup the name on the script context table first (lexical scoping). | |
496 ScriptContextTableLookupResult result; | |
497 if (LookupInScriptContextTable(name, &result)) { | |
498 if (result.context->is_the_hole(isolate(), result.index)) return NoChange(); | |
499 if (result.immutable) return NoChange(); | |
500 Node* context = jsgraph()->HeapConstant(result.context); | |
501 effect = graph()->NewNode(javascript()->StoreContext(0, result.index), | |
502 value, context, effect, control); | |
503 ReplaceWithValue(node, value, effect, control); | |
504 return Replace(value); | |
505 } | |
506 | |
507 // Not much we can do if deoptimization support is disabled. | |
508 if (!(flags() & kDeoptimizationEnabled)) return NoChange(); | |
509 | |
510 // Lookup the {name} on the global object instead. | |
511 return ReduceGlobalAccess(node, nullptr, value, name, AccessMode::kStore); | |
512 } | |
513 | |
258 Reduction JSNativeContextSpecialization::ReduceNamedAccess( | 514 Reduction JSNativeContextSpecialization::ReduceNamedAccess( |
259 Node* node, Node* value, MapHandleList const& receiver_maps, | 515 Node* node, Node* value, MapHandleList const& receiver_maps, |
260 Handle<Name> name, AccessMode access_mode, LanguageMode language_mode, | 516 Handle<Name> name, AccessMode access_mode, LanguageMode language_mode, |
261 Handle<TypeFeedbackVector> vector, FeedbackVectorSlot slot, Node* index) { | 517 Handle<TypeFeedbackVector> vector, FeedbackVectorSlot slot, Node* index) { |
262 DCHECK(node->opcode() == IrOpcode::kJSLoadNamed || | 518 DCHECK(node->opcode() == IrOpcode::kJSLoadNamed || |
263 node->opcode() == IrOpcode::kJSStoreNamed || | 519 node->opcode() == IrOpcode::kJSStoreNamed || |
264 node->opcode() == IrOpcode::kJSLoadProperty || | 520 node->opcode() == IrOpcode::kJSLoadProperty || |
265 node->opcode() == IrOpcode::kJSStoreProperty); | 521 node->opcode() == IrOpcode::kJSStoreProperty); |
266 Node* receiver = NodeProperties::GetValueInput(node, 0); | 522 Node* receiver = NodeProperties::GetValueInput(node, 0); |
267 Node* context = NodeProperties::GetContextInput(node); | 523 Node* context = NodeProperties::GetContextInput(node); |
268 Node* frame_state_eager = NodeProperties::FindFrameStateBefore(node); | 524 Node* frame_state_eager = NodeProperties::FindFrameStateBefore(node); |
269 Node* frame_state_lazy = NodeProperties::GetFrameStateInput(node); | 525 Node* frame_state_lazy = NodeProperties::GetFrameStateInput(node); |
270 Node* effect = NodeProperties::GetEffectInput(node); | 526 Node* effect = NodeProperties::GetEffectInput(node); |
271 Node* control = NodeProperties::GetControlInput(node); | 527 Node* control = NodeProperties::GetControlInput(node); |
272 | 528 |
273 // Not much we can do if deoptimization support is disabled. | 529 // Not much we can do if deoptimization support is disabled. |
274 if (!(flags() & kDeoptimizationEnabled)) return NoChange(); | 530 if (!(flags() & kDeoptimizationEnabled)) return NoChange(); |
275 | 531 |
532 // Check if we have an access o.x or o.x=v where o is the current | |
533 // native contexts' global proxy, and turn that into a direct access | |
534 // to the current native contexts' global object instead. | |
535 if (receiver_maps.length() == 1) { | |
536 Handle<Map> receiver_map = receiver_maps.first(); | |
537 if (receiver_map->IsJSGlobalProxyMap()) { | |
538 Handle<JSFunction> receiver_constructor = | |
539 handle(JSFunction::cast(receiver_map->GetConstructor()), isolate()); | |
Igor Sheludko
2017/01/30 23:09:33
s/ = handle//
Benedikt Meurer
2017/01/31 04:55:10
Done.
| |
540 if (receiver_constructor->native_context() == *native_context()) { | |
541 return ReduceGlobalAccess(node, receiver, value, name, access_mode); | |
542 } | |
543 } | |
544 } | |
545 | |
276 // Compute property access infos for the receiver maps. | 546 // Compute property access infos for the receiver maps. |
277 AccessInfoFactory access_info_factory(dependencies(), native_context(), | 547 AccessInfoFactory access_info_factory(dependencies(), native_context(), |
278 graph()->zone()); | 548 graph()->zone()); |
279 ZoneVector<PropertyAccessInfo> access_infos(zone()); | 549 ZoneVector<PropertyAccessInfo> access_infos(zone()); |
280 if (!access_info_factory.ComputePropertyAccessInfos( | 550 if (!access_info_factory.ComputePropertyAccessInfos( |
281 receiver_maps, name, access_mode, &access_infos)) { | 551 receiver_maps, name, access_mode, &access_infos)) { |
282 return NoChange(); | 552 return NoChange(); |
283 } | 553 } |
284 | 554 |
285 // TODO(turbofan): Add support for inlining into try blocks. | 555 // TODO(turbofan): Add support for inlining into try blocks. |
(...skipping 194 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
480 } | 750 } |
481 | 751 |
482 Reduction JSNativeContextSpecialization::ReduceNamedAccessFromNexus( | 752 Reduction JSNativeContextSpecialization::ReduceNamedAccessFromNexus( |
483 Node* node, Node* value, FeedbackNexus const& nexus, Handle<Name> name, | 753 Node* node, Node* value, FeedbackNexus const& nexus, Handle<Name> name, |
484 AccessMode access_mode, LanguageMode language_mode) { | 754 AccessMode access_mode, LanguageMode language_mode) { |
485 DCHECK(node->opcode() == IrOpcode::kJSLoadNamed || | 755 DCHECK(node->opcode() == IrOpcode::kJSLoadNamed || |
486 node->opcode() == IrOpcode::kJSStoreNamed); | 756 node->opcode() == IrOpcode::kJSStoreNamed); |
487 Node* const receiver = NodeProperties::GetValueInput(node, 0); | 757 Node* const receiver = NodeProperties::GetValueInput(node, 0); |
488 Node* const effect = NodeProperties::GetEffectInput(node); | 758 Node* const effect = NodeProperties::GetEffectInput(node); |
489 | 759 |
760 // Check if we are accessing the current native contexts' global proxy. | |
761 HeapObjectMatcher m(receiver); | |
762 if (m.HasValue() && m.Value().is_identical_to(global_proxy())) { | |
763 // Optimize accesses to the current native contexts' global proxy. | |
764 return ReduceGlobalAccess(node, nullptr, value, name, access_mode); | |
765 } | |
766 | |
490 // Check if the {nexus} reports type feedback for the IC. | 767 // Check if the {nexus} reports type feedback for the IC. |
491 if (nexus.IsUninitialized()) { | 768 if (nexus.IsUninitialized()) { |
492 if ((flags() & kDeoptimizationEnabled) && | 769 if ((flags() & kDeoptimizationEnabled) && |
493 (flags() & kBailoutOnUninitialized)) { | 770 (flags() & kBailoutOnUninitialized)) { |
494 return ReduceSoftDeoptimize( | 771 return ReduceSoftDeoptimize( |
495 node, | 772 node, |
496 DeoptimizeReason::kInsufficientTypeFeedbackForGenericNamedAccess); | 773 DeoptimizeReason::kInsufficientTypeFeedbackForGenericNamedAccess); |
497 } | 774 } |
498 return NoChange(); | 775 return NoChange(); |
499 } | 776 } |
(...skipping 10 matching lines...) Expand all Loading... | |
510 DeoptimizeReason::kInsufficientTypeFeedbackForGenericNamedAccess); | 787 DeoptimizeReason::kInsufficientTypeFeedbackForGenericNamedAccess); |
511 } | 788 } |
512 return NoChange(); | 789 return NoChange(); |
513 } | 790 } |
514 | 791 |
515 // Try to lower the named access based on the {receiver_maps}. | 792 // Try to lower the named access based on the {receiver_maps}. |
516 return ReduceNamedAccess(node, value, receiver_maps, name, access_mode, | 793 return ReduceNamedAccess(node, value, receiver_maps, name, access_mode, |
517 language_mode, nexus.vector_handle(), nexus.slot()); | 794 language_mode, nexus.vector_handle(), nexus.slot()); |
518 } | 795 } |
519 | 796 |
520 | |
521 Reduction JSNativeContextSpecialization::ReduceJSLoadNamed(Node* node) { | 797 Reduction JSNativeContextSpecialization::ReduceJSLoadNamed(Node* node) { |
522 DCHECK_EQ(IrOpcode::kJSLoadNamed, node->opcode()); | 798 DCHECK_EQ(IrOpcode::kJSLoadNamed, node->opcode()); |
523 NamedAccess const& p = NamedAccessOf(node->op()); | 799 NamedAccess const& p = NamedAccessOf(node->op()); |
524 Node* const receiver = NodeProperties::GetValueInput(node, 0); | 800 Node* const receiver = NodeProperties::GetValueInput(node, 0); |
525 Node* const value = jsgraph()->Dead(); | 801 Node* const value = jsgraph()->Dead(); |
526 | 802 |
527 // Check if we have a constant receiver. | 803 // Check if we have a constant receiver. |
528 HeapObjectMatcher m(receiver); | 804 HeapObjectMatcher m(receiver); |
529 if (m.HasValue()) { | 805 if (m.HasValue()) { |
530 if (m.Value()->IsJSFunction() && | 806 if (m.Value()->IsJSFunction() && |
(...skipping 1404 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1935 if (initial_map->constructor_or_backpointer() == *mnewtarget.Value()) { | 2211 if (initial_map->constructor_or_backpointer() == *mnewtarget.Value()) { |
1936 DCHECK_EQ(*initial_map, initial_map->FindRootMap()); | 2212 DCHECK_EQ(*initial_map, initial_map->FindRootMap()); |
1937 return initial_map; | 2213 return initial_map; |
1938 } | 2214 } |
1939 } | 2215 } |
1940 } | 2216 } |
1941 } | 2217 } |
1942 return MaybeHandle<Map>(); | 2218 return MaybeHandle<Map>(); |
1943 } | 2219 } |
1944 | 2220 |
2221 bool JSNativeContextSpecialization::LookupInScriptContextTable( | |
2222 Handle<Name> name, ScriptContextTableLookupResult* result) { | |
2223 if (!name->IsString()) return false; | |
2224 Handle<ScriptContextTable> script_context_table( | |
2225 global_object()->native_context()->script_context_table(), isolate()); | |
2226 ScriptContextTable::LookupResult lookup_result; | |
2227 if (!ScriptContextTable::Lookup(script_context_table, | |
2228 Handle<String>::cast(name), &lookup_result)) { | |
2229 return false; | |
2230 } | |
2231 Handle<Context> script_context = ScriptContextTable::GetContext( | |
2232 script_context_table, lookup_result.context_index); | |
2233 result->context = script_context; | |
2234 result->immutable = lookup_result.mode == CONST; | |
2235 result->index = lookup_result.slot_index; | |
2236 return true; | |
2237 } | |
2238 | |
1945 Graph* JSNativeContextSpecialization::graph() const { | 2239 Graph* JSNativeContextSpecialization::graph() const { |
1946 return jsgraph()->graph(); | 2240 return jsgraph()->graph(); |
1947 } | 2241 } |
1948 | 2242 |
1949 Isolate* JSNativeContextSpecialization::isolate() const { | 2243 Isolate* JSNativeContextSpecialization::isolate() const { |
1950 return jsgraph()->isolate(); | 2244 return jsgraph()->isolate(); |
1951 } | 2245 } |
1952 | 2246 |
1953 Factory* JSNativeContextSpecialization::factory() const { | 2247 Factory* JSNativeContextSpecialization::factory() const { |
1954 return isolate()->factory(); | 2248 return isolate()->factory(); |
(...skipping 11 matching lines...) Expand all Loading... | |
1966 return jsgraph()->javascript(); | 2260 return jsgraph()->javascript(); |
1967 } | 2261 } |
1968 | 2262 |
1969 SimplifiedOperatorBuilder* JSNativeContextSpecialization::simplified() const { | 2263 SimplifiedOperatorBuilder* JSNativeContextSpecialization::simplified() const { |
1970 return jsgraph()->simplified(); | 2264 return jsgraph()->simplified(); |
1971 } | 2265 } |
1972 | 2266 |
1973 } // namespace compiler | 2267 } // namespace compiler |
1974 } // namespace internal | 2268 } // namespace internal |
1975 } // namespace v8 | 2269 } // namespace v8 |
OLD | NEW |