OLD | NEW |
1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 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/instruction-selector.h" | 5 #include "src/compiler/instruction-selector.h" |
6 | 6 |
7 #include <limits> | 7 #include <limits> |
8 | 8 |
9 #include "src/base/adapters.h" | 9 #include "src/base/adapters.h" |
10 #include "src/compiler/compiler-source-position-table.h" | 10 #include "src/compiler/compiler-source-position-table.h" |
(...skipping 398 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
409 } | 409 } |
410 | 410 |
411 | 411 |
412 void InstructionSelector::MarkAsRepresentation(MachineRepresentation rep, | 412 void InstructionSelector::MarkAsRepresentation(MachineRepresentation rep, |
413 Node* node) { | 413 Node* node) { |
414 sequence()->MarkAsRepresentation(rep, GetVirtualRegister(node)); | 414 sequence()->MarkAsRepresentation(rep, GetVirtualRegister(node)); |
415 } | 415 } |
416 | 416 |
417 namespace { | 417 namespace { |
418 | 418 |
419 InstructionOperand OperandForDeopt(OperandGenerator* g, Node* input, | 419 InstructionOperand OperandForDeopt(Isolate* isolate, OperandGenerator* g, |
420 FrameStateInputKind kind, | 420 Node* input, FrameStateInputKind kind, |
421 MachineRepresentation rep) { | 421 MachineRepresentation rep) { |
422 if (rep == MachineRepresentation::kNone) { | 422 if (rep == MachineRepresentation::kNone) { |
423 return g->TempImmediate(FrameStateDescriptor::kImpossibleValue); | 423 return g->TempImmediate(FrameStateDescriptor::kImpossibleValue); |
424 } | 424 } |
425 | 425 |
426 switch (input->opcode()) { | 426 switch (input->opcode()) { |
427 case IrOpcode::kInt32Constant: | 427 case IrOpcode::kInt32Constant: |
428 case IrOpcode::kInt64Constant: | 428 case IrOpcode::kInt64Constant: |
429 case IrOpcode::kNumberConstant: | 429 case IrOpcode::kNumberConstant: |
430 case IrOpcode::kFloat32Constant: | 430 case IrOpcode::kFloat32Constant: |
431 case IrOpcode::kFloat64Constant: | 431 case IrOpcode::kFloat64Constant: |
432 case IrOpcode::kHeapConstant: | |
433 return g->UseImmediate(input); | 432 return g->UseImmediate(input); |
| 433 case IrOpcode::kHeapConstant: { |
| 434 if (!CanBeTaggedPointer(rep)) { |
| 435 // If we have inconsistent static and dynamic types, e.g. if we |
| 436 // smi-check a string, we can get here with a heap object that |
| 437 // says it is a smi. In that case, we return an invalid instruction |
| 438 // operand, which will be interpreted as an optimized-out value. |
| 439 |
| 440 // TODO(jarin) Ideally, we should turn the current instruction |
| 441 // into an abort (we should never execute it). |
| 442 return InstructionOperand(); |
| 443 } |
| 444 |
| 445 Handle<HeapObject> constant = OpParameter<Handle<HeapObject>>(input); |
| 446 Heap::RootListIndex root_index; |
| 447 if (isolate->heap()->IsRootHandle(constant, &root_index) && |
| 448 root_index == Heap::kOptimizedOutRootIndex) { |
| 449 // For an optimized-out object we return an invalid instruction |
| 450 // operand, so that we take the fast path for optimized-out values. |
| 451 return InstructionOperand(); |
| 452 } |
| 453 |
| 454 return g->UseImmediate(input); |
| 455 } |
434 case IrOpcode::kObjectState: | 456 case IrOpcode::kObjectState: |
435 case IrOpcode::kTypedObjectState: | 457 case IrOpcode::kTypedObjectState: |
436 UNREACHABLE(); | 458 UNREACHABLE(); |
437 break; | 459 break; |
438 default: | 460 default: |
439 switch (kind) { | 461 switch (kind) { |
440 case FrameStateInputKind::kStackSlot: | 462 case FrameStateInputKind::kStackSlot: |
441 return g->UseUniqueSlot(input); | 463 return g->UseUniqueSlot(input); |
442 case FrameStateInputKind::kAny: | 464 case FrameStateInputKind::kAny: |
443 // Currently deopts "wrap" other operations, so the deopt's inputs | 465 // Currently deopts "wrap" other operations, so the deopt's inputs |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
501 return entries; | 523 return entries; |
502 } else { | 524 } else { |
503 // Crankshaft counts duplicate objects for the running id, so we have | 525 // Crankshaft counts duplicate objects for the running id, so we have |
504 // to push the input again. | 526 // to push the input again. |
505 deduplicator->InsertObject(input); | 527 deduplicator->InsertObject(input); |
506 values->PushDuplicate(id); | 528 values->PushDuplicate(id); |
507 return 0; | 529 return 0; |
508 } | 530 } |
509 } | 531 } |
510 default: { | 532 default: { |
511 Heap* const heap = isolate()->heap(); | 533 InstructionOperand op = |
512 if (input->opcode() == IrOpcode::kHeapConstant) { | 534 OperandForDeopt(isolate(), g, input, kind, type.representation()); |
513 Handle<HeapObject> constant = OpParameter<Handle<HeapObject>>(input); | 535 if (op.kind() == InstructionOperand::INVALID) { |
514 Heap::RootListIndex root_index; | 536 // Invalid operand means the value is impossible or optimized-out. |
515 if (heap->IsRootHandle(constant, &root_index) && | 537 values->PushOptimizedOut(); |
516 root_index == Heap::kOptimizedOutRootIndex) { | 538 return 0; |
517 values->PushOptimizedOut(); | 539 } else { |
518 return 0; | 540 inputs->push_back(op); |
519 } | 541 values->PushPlain(type); |
| 542 return 1; |
520 } | 543 } |
521 inputs->push_back(OperandForDeopt(g, input, kind, type.representation())); | |
522 values->PushPlain(type); | |
523 return 1; | |
524 } | 544 } |
525 } | 545 } |
526 } | 546 } |
527 | 547 |
528 | 548 |
529 // Returns the number of instruction operands added to inputs. | 549 // Returns the number of instruction operands added to inputs. |
530 size_t InstructionSelector::AddInputsToFrameStateDescriptor( | 550 size_t InstructionSelector::AddInputsToFrameStateDescriptor( |
531 FrameStateDescriptor* descriptor, Node* state, OperandGenerator* g, | 551 FrameStateDescriptor* descriptor, Node* state, OperandGenerator* g, |
532 StateObjectDeduplicator* deduplicator, InstructionOperandVector* inputs, | 552 StateObjectDeduplicator* deduplicator, InstructionOperandVector* inputs, |
533 FrameStateInputKind kind, Zone* zone) { | 553 FrameStateInputKind kind, Zone* zone) { |
(...skipping 1596 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2130 return new (instruction_zone()) FrameStateDescriptor( | 2150 return new (instruction_zone()) FrameStateDescriptor( |
2131 instruction_zone(), state_info.type(), state_info.bailout_id(), | 2151 instruction_zone(), state_info.type(), state_info.bailout_id(), |
2132 state_info.state_combine(), parameters, locals, stack, | 2152 state_info.state_combine(), parameters, locals, stack, |
2133 state_info.shared_info(), outer_state); | 2153 state_info.shared_info(), outer_state); |
2134 } | 2154 } |
2135 | 2155 |
2136 | 2156 |
2137 } // namespace compiler | 2157 } // namespace compiler |
2138 } // namespace internal | 2158 } // namespace internal |
2139 } // namespace v8 | 2159 } // namespace v8 |
OLD | NEW |