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

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

Issue 2692753004: [turbofan] escape analysis supports arguments object and rest elements (Closed)
Patch Set: handle the case where Deoptimizer::function_ is a Smi Created 3 years, 9 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/escape-analysis-reducer.h ('k') | src/compiler/graph-assembler.h » ('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/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 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
77 break; 79 break;
78 default: 80 default:
79 break; 81 break;
80 } 82 }
81 } 83 }
82 if (!depends_on_object_state) { 84 if (!depends_on_object_state) {
83 fully_reduced_.Add(node->id()); 85 fully_reduced_.Add(node->id());
84 } 86 }
85 return NoChange(); 87 return NoChange();
86 } 88 }
89 case IrOpcode::kNewUnmappedArgumentsElements:
90 arguments_elements_.insert(node);
91 break;
87 default: 92 default:
88 // TODO(sigurds): Change this to GetFrameStateInputCount once 93 // TODO(sigurds): Change this to GetFrameStateInputCount once
89 // it is working. For now we use EffectInputCount > 0 to determine 94 // it is working. For now we use EffectInputCount > 0 to determine
90 // whether a node might have a frame state input. 95 // whether a node might have a frame state input.
91 if (exists_virtual_allocate_ && node->op()->EffectInputCount() > 0) { 96 if (exists_virtual_allocate_ && node->op()->EffectInputCount() > 0) {
92 return ReduceFrameStateUses(node); 97 return ReduceFrameStateUses(node);
93 } 98 }
94 break; 99 break;
95 } 100 }
96 return NoChange(); 101 return NoChange();
(...skipping 276 matching lines...) Expand 10 before | Expand all | Expand 10 after
373 #ifdef DEBUG 378 #ifdef DEBUG
374 AllNodes all(zone(), jsgraph()->graph()); 379 AllNodes all(zone(), jsgraph()->graph());
375 for (Node* node : all.reachable) { 380 for (Node* node : all.reachable) {
376 if (node->opcode() == IrOpcode::kAllocate) { 381 if (node->opcode() == IrOpcode::kAllocate) {
377 CHECK(!escape_analysis_->IsVirtual(node)); 382 CHECK(!escape_analysis_->IsVirtual(node));
378 } 383 }
379 } 384 }
380 #endif // DEBUG 385 #endif // DEBUG
381 } 386 }
382 387
388 void EscapeAnalysisReducer::Finalize() {
389 for (Node* node : arguments_elements_) {
390 DCHECK(node->opcode() == IrOpcode::kNewUnmappedArgumentsElements);
391
392 Node* arguments_frame = NodeProperties::GetValueInput(node, 0);
393 if (arguments_frame->opcode() != IrOpcode::kArgumentsFrame) continue;
394 Node* arguments_length = NodeProperties::GetValueInput(node, 1);
395 if (arguments_length->opcode() != IrOpcode::kArgumentsLength) continue;
396
397 bool escaping_use = false;
398 ZoneVector<Node*> loads(zone());
399 for (Edge edge : node->use_edges()) {
400 Node* use = edge.from();
401 if (!NodeProperties::IsValueEdge(edge)) continue;
402 if (use->use_edges().empty()) {
403 // A node without uses is dead, so we don't have to care about it.
404 continue;
405 }
406 switch (use->opcode()) {
407 case IrOpcode::kStateValues:
408 case IrOpcode::kTypedStateValues:
409 case IrOpcode::kObjectState:
410 case IrOpcode::kTypedObjectState:
411 break;
412 case IrOpcode::kLoadElement:
413 loads.push_back(use);
414 break;
415 case IrOpcode::kLoadField:
416 if (FieldAccessOf(use->op()).offset == FixedArray::kLengthOffset) {
417 loads.push_back(use);
418 } else {
419 escaping_use = true;
420 }
421 break;
422 default:
423 // If the arguments elements node node is used by an unhandled node,
424 // then we cannot remove this allocation.
425 escaping_use = true;
426 break;
427 }
428 if (escaping_use) break;
429 }
430 if (!escaping_use) {
431 Node* arguments_elements_state = jsgraph()->graph()->NewNode(
432 jsgraph()->common()->ArgumentsElementsState(
433 IsRestLengthOf(arguments_length->op())));
434 NodeProperties::SetType(arguments_elements_state, Type::OtherInternal());
435 ReplaceWithValue(node, arguments_elements_state);
436
437 ElementAccess stack_access;
438 stack_access.base_is_tagged = BaseTaggedness::kUntaggedBase;
439 // Reduce base address by {kPointerSize} such that (length - index)
440 // resolves to the right position.
441 stack_access.header_size =
442 CommonFrameConstants::kFixedFrameSizeAboveFp - kPointerSize;
443 stack_access.type = Type::NonInternal();
444 stack_access.machine_type = MachineType::AnyTagged();
445 stack_access.write_barrier_kind = WriteBarrierKind::kNoWriteBarrier;
446 const Operator* load_stack_op =
447 jsgraph()->simplified()->LoadElement(stack_access);
448
449 for (Node* load : loads) {
450 switch (load->opcode()) {
451 case IrOpcode::kLoadElement: {
452 Node* index = NodeProperties::GetValueInput(load, 1);
453 // {offset} is a reverted index starting from 1. The base address is
454 // adapted to allow offsets starting from 1.
455 Node* offset = jsgraph()->graph()->NewNode(
456 jsgraph()->simplified()->NumberSubtract(), arguments_length,
457 index);
458 NodeProperties::SetType(offset,
459 TypeCache::Get().kArgumentsLengthType);
460 NodeProperties::ReplaceValueInput(load, arguments_frame, 0);
461 NodeProperties::ReplaceValueInput(load, offset, 1);
462 NodeProperties::ChangeOp(load, load_stack_op);
463 break;
464 }
465 case IrOpcode::kLoadField: {
466 DCHECK_EQ(FieldAccessOf(load->op()).offset,
467 FixedArray::kLengthOffset);
468 Node* length = NodeProperties::GetValueInput(node, 1);
469 ReplaceWithValue(load, length);
470 break;
471 }
472 default:
473 UNREACHABLE();
474 }
475 }
476 }
477 }
478 }
479
383 } // namespace compiler 480 } // namespace compiler
384 } // namespace internal 481 } // namespace internal
385 } // namespace v8 482 } // namespace v8
OLDNEW
« no previous file with comments | « src/compiler/escape-analysis-reducer.h ('k') | src/compiler/graph-assembler.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698