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

Side by Side Diff: src/compiler/js-native-context-specialization.cc

Issue 2664853002: [turbofan] Support fast access to the current global object. (Closed)
Patch Set: Created 3 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-native-context-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-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
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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « src/compiler/js-native-context-specialization.h ('k') | src/compiler/pipeline.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698