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

Side by Side Diff: src/compiler/escape-analysis-reducer.cc

Issue 2692753004: [turbofan] escape analysis supports arguments object and rest elements (Closed)
Patch Set: addressed comments 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
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/escape-analysis-reducer.h" 5 #include "src/compiler/escape-analysis-reducer.h"
6 6
7 #include "src/compiler/all-nodes.h" 7 #include "src/compiler/all-nodes.h"
8 #include "src/compiler/js-graph.h" 8 #include "src/compiler/js-graph.h"
9 #include "src/compiler/simplified-operator.h"
10 #include "src/compiler/type-cache.h"
9 #include "src/counters.h" 11 #include "src/counters.h"
10 12
11 namespace v8 { 13 namespace v8 {
12 namespace internal { 14 namespace internal {
13 namespace compiler { 15 namespace compiler {
14 16
15 #ifdef DEBUG 17 #ifdef DEBUG
16 #define TRACE(...) \ 18 #define TRACE(...) \
17 do { \ 19 do { \
18 if (FLAG_trace_turbo_escape) PrintF(__VA_ARGS__); \ 20 if (FLAG_trace_turbo_escape) PrintF(__VA_ARGS__); \
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
79 break; 81 break;
80 default: 82 default:
81 break; 83 break;
82 } 84 }
83 } 85 }
84 if (!depends_on_object_state) { 86 if (!depends_on_object_state) {
85 fully_reduced_.Add(node->id()); 87 fully_reduced_.Add(node->id());
86 } 88 }
87 return NoChange(); 89 return NoChange();
88 } 90 }
91 case IrOpcode::kNewUnmappedArgumentsElements:
92 arguments_elements_.insert(node);
93 // Fallthrough.
Jarin 2017/02/27 13:24:34 Could we get rid of the fallthrough? Case fallthr
89 default: 94 default:
90 // TODO(sigurds): Change this to GetFrameStateInputCount once 95 // TODO(sigurds): Change this to GetFrameStateInputCount once
91 // it is working. For now we use EffectInputCount > 0 to determine 96 // it is working. For now we use EffectInputCount > 0 to determine
92 // whether a node might have a frame state input. 97 // whether a node might have a frame state input.
93 if (exists_virtual_allocate_ && node->op()->EffectInputCount() > 0) { 98 if (exists_virtual_allocate_ && node->op()->EffectInputCount() > 0) {
94 return ReduceFrameStateUses(node); 99 return ReduceFrameStateUses(node);
95 } 100 }
96 break; 101 break;
97 } 102 }
98 return NoChange(); 103 return NoChange();
(...skipping 291 matching lines...) Expand 10 before | Expand all | Expand 10 after
390 #ifdef DEBUG 395 #ifdef DEBUG
391 AllNodes all(zone(), jsgraph()->graph()); 396 AllNodes all(zone(), jsgraph()->graph());
392 for (Node* node : all.reachable) { 397 for (Node* node : all.reachable) {
393 if (node->opcode() == IrOpcode::kAllocate) { 398 if (node->opcode() == IrOpcode::kAllocate) {
394 CHECK(!escape_analysis_->IsVirtual(node)); 399 CHECK(!escape_analysis_->IsVirtual(node));
395 } 400 }
396 } 401 }
397 #endif // DEBUG 402 #endif // DEBUG
398 } 403 }
399 404
405 void EscapeAnalysisReducer::Finalize() {
406 for (Node* node : arguments_elements_) {
407 DCHECK(node->opcode() == IrOpcode::kNewUnmappedArgumentsElements);
408
409 Node* arguments_frame = NodeProperties::GetValueInput(node, 0);
410 if (arguments_frame->opcode() != IrOpcode::kArgumentsFrame) continue;
411 Node* arguments_length = NodeProperties::GetValueInput(node, 1);
412 if (arguments_length->opcode() != IrOpcode::kArgumentsLength) continue;
413
414 bool escaping_use = false;
415 ZoneVector<Node*> loads(zone());
416 for (Edge edge : node->use_edges()) {
417 Node* use = edge.from();
418 if (!NodeProperties::IsValueEdge(edge)) continue;
419 switch (use->opcode()) {
420 case IrOpcode::kStateValues:
421 case IrOpcode::kTypedStateValues:
422 case IrOpcode::kObjectState:
423 case IrOpcode::kTypedObjectState:
424 break;
425 case IrOpcode::kLoadElement:
426 loads.push_back(use);
427 break;
428 case IrOpcode::kLoadField:
429 if (FieldAccessOf(use->op()).offset == FixedArray::kLengthOffset) {
430 loads.push_back(use);
431 break;
432 }
433 // Fallthrough.
Jarin 2017/02/27 13:24:34 Could not you say here if (...) { load.push_bac
434 default:
435 if (!use->use_edges().empty()) {
Jarin 2017/02/27 13:24:34 Explain in a comment what this check does, please.
436 escaping_use = true;
437 break;
438 }
439 }
440 if (escaping_use) break;
441 }
442 if (!escaping_use) {
443 int formal_parameter_count =
444 FormalParameterCountOf(arguments_length->op());
445 Node* arguments_elements_state = jsgraph()->graph()->NewNode(
446 jsgraph()->common()->ArgumentsElementsState(
447 IsRestLengthOf(arguments_length->op())));
448 NodeProperties::SetType(arguments_elements_state, Type::OtherInternal());
449 ReplaceWithValue(node, arguments_elements_state);
450
451 ElementAccess stack_access;
452 stack_access.base_is_tagged = BaseTaggedness::kUntaggedBase;
453 // Reduce base address by {kPointerSize} such that (length - index)
454 // resolves to the right position.
455 stack_access.header_size =
456 CommonFrameConstants::kFixedFrameSizeAboveFp - kPointerSize;
457 stack_access.type = Type::NonInternal();
458 stack_access.machine_type = MachineType::AnyTagged();
459 stack_access.write_barrier_kind = WriteBarrierKind::kNoWriteBarrier;
460 const Operator* load_stack_op =
461 jsgraph()->simplified()->LoadElement(stack_access);
462
463 for (Node* load : loads) {
464 switch (load->opcode()) {
465 case IrOpcode::kLoadElement: {
466 Node* index = NodeProperties::GetValueInput(load, 1);
467 // {offset} is a reverted index starting from 1. The base address is
468 // adapted to allow offsets starting from 1.
469 Node* offset = jsgraph()->graph()->NewNode(
470 jsgraph()->simplified()->NumberSubtract(), arguments_length,
471 index);
472 NodeProperties::SetType(offset,
473 TypeCache::Get().kArgumentsLengthType);
474 NodeProperties::ReplaceValueInput(load, arguments_frame, 0);
475 NodeProperties::ReplaceValueInput(load, offset, 1);
476 NodeProperties::ChangeOp(load, load_stack_op);
477 break;
478 }
479 case IrOpcode::kLoadField: {
480 DCHECK_EQ(FieldAccessOf(load->op()).offset,
481 FixedArray::kLengthOffset);
482 Node* length = NodeProperties::GetValueInput(node, 1);
483 ReplaceWithValue(load, length);
484 break;
485 }
486 default:
487 UNREACHABLE();
488 }
489 }
490 }
491 }
492 }
493
400 } // namespace compiler 494 } // namespace compiler
401 } // namespace internal 495 } // namespace internal
402 } // namespace v8 496 } // namespace v8
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698