| OLD | NEW |
| 1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 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/code-generator.h" | 5 #include "src/compiler/code-generator.h" |
| 6 | 6 |
| 7 #include "src/address-map.h" | 7 #include "src/address-map.h" |
| 8 #include "src/compiler/code-generator-impl.h" | 8 #include "src/compiler/code-generator-impl.h" |
| 9 #include "src/compiler/linkage.h" | 9 #include "src/compiler/linkage.h" |
| 10 #include "src/compiler/pipeline.h" | 10 #include "src/compiler/pipeline.h" |
| (...skipping 198 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 209 | 209 |
| 210 // Emit a code line info recording stop event. | 210 // Emit a code line info recording stop event. |
| 211 void* line_info = recorder->DetachJITHandlerData(); | 211 void* line_info = recorder->DetachJITHandlerData(); |
| 212 LOG_CODE_EVENT(isolate(), CodeEndLinePosInfoRecordEvent(*result, line_info)); | 212 LOG_CODE_EVENT(isolate(), CodeEndLinePosInfoRecordEvent(*result, line_info)); |
| 213 | 213 |
| 214 return result; | 214 return result; |
| 215 } | 215 } |
| 216 | 216 |
| 217 | 217 |
| 218 bool CodeGenerator::IsNextInAssemblyOrder(RpoNumber block) const { | 218 bool CodeGenerator::IsNextInAssemblyOrder(RpoNumber block) const { |
| 219 return code()->InstructionBlockAt(current_block_)->ao_number().IsNext( | 219 return code() |
| 220 code()->InstructionBlockAt(block)->ao_number()); | 220 ->InstructionBlockAt(current_block_) |
| 221 ->ao_number() |
| 222 .IsNext(code()->InstructionBlockAt(block)->ao_number()); |
| 221 } | 223 } |
| 222 | 224 |
| 223 | 225 |
| 224 void CodeGenerator::RecordSafepoint(ReferenceMap* references, | 226 void CodeGenerator::RecordSafepoint(ReferenceMap* references, |
| 225 Safepoint::Kind kind, int arguments, | 227 Safepoint::Kind kind, int arguments, |
| 226 Safepoint::DeoptMode deopt_mode) { | 228 Safepoint::DeoptMode deopt_mode) { |
| 227 Safepoint safepoint = | 229 Safepoint safepoint = |
| 228 safepoints()->DefineSafepoint(masm(), kind, arguments, deopt_mode); | 230 safepoints()->DefineSafepoint(masm(), kind, arguments, deopt_mode); |
| 229 int stackSlotToSpillSlotDelta = | 231 int stackSlotToSpillSlotDelta = |
| 230 frame()->GetTotalFrameSlotCount() - frame()->GetSpillSlotCount(); | 232 frame()->GetTotalFrameSlotCount() - frame()->GetSpillSlotCount(); |
| (...skipping 251 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 482 | 484 |
| 483 FrameStateDescriptor* CodeGenerator::GetFrameStateDescriptor( | 485 FrameStateDescriptor* CodeGenerator::GetFrameStateDescriptor( |
| 484 Instruction* instr, size_t frame_state_offset) { | 486 Instruction* instr, size_t frame_state_offset) { |
| 485 InstructionOperandConverter i(this, instr); | 487 InstructionOperandConverter i(this, instr); |
| 486 InstructionSequence::StateId state_id = | 488 InstructionSequence::StateId state_id = |
| 487 InstructionSequence::StateId::FromInt(i.InputInt32(frame_state_offset)); | 489 InstructionSequence::StateId::FromInt(i.InputInt32(frame_state_offset)); |
| 488 return code()->GetFrameStateDescriptor(state_id); | 490 return code()->GetFrameStateDescriptor(state_id); |
| 489 } | 491 } |
| 490 | 492 |
| 491 | 493 |
| 492 namespace { | 494 void CodeGenerator::TranslateStateValueDescriptor( |
| 493 | 495 StateValueDescriptor* desc, Translation* translation, |
| 494 struct OperandAndType { | 496 InstructionOperandIterator* iter) { |
| 495 InstructionOperand* const operand; | 497 if (desc->IsNested()) { |
| 496 MachineType const type; | 498 translation->BeginCapturedObject(static_cast<int>(desc->size())); |
| 497 }; | 499 for (size_t index = 0; index < desc->fields().size(); index++) { |
| 500 TranslateStateValueDescriptor(&desc->fields()[index], translation, iter); |
| 501 } |
| 502 } else if (desc->IsDuplicate()) { |
| 503 translation->DuplicateObject(static_cast<int>(desc->id())); |
| 504 } else { |
| 505 DCHECK(desc->IsPlain()); |
| 506 AddTranslationForOperand(translation, iter->instruction(), iter->Advance(), |
| 507 desc->type()); |
| 508 } |
| 509 } |
| 498 | 510 |
| 499 | 511 |
| 500 OperandAndType TypedOperandForFrameState(FrameStateDescriptor* descriptor, | 512 void CodeGenerator::TranslateFrameStateDescriptorOperands( |
| 501 Instruction* instr, | 513 FrameStateDescriptor* desc, InstructionOperandIterator* iter, |
| 502 size_t frame_state_offset, | 514 OutputFrameStateCombine combine, Translation* translation) { |
| 503 size_t index, | 515 for (size_t index = 0; index < desc->GetSize(combine); index++) { |
| 504 OutputFrameStateCombine combine) { | 516 switch (combine.kind()) { |
| 505 DCHECK(index < descriptor->GetSize(combine)); | 517 case OutputFrameStateCombine::kPushOutput: { |
| 506 switch (combine.kind()) { | 518 DCHECK(combine.GetPushCount() <= iter->instruction()->OutputCount()); |
| 507 case OutputFrameStateCombine::kPushOutput: { | 519 size_t size_without_output = |
| 508 DCHECK(combine.GetPushCount() <= instr->OutputCount()); | 520 desc->GetSize(OutputFrameStateCombine::Ignore()); |
| 509 size_t size_without_output = | 521 // If the index is past the existing stack items in values_. |
| 510 descriptor->GetSize(OutputFrameStateCombine::Ignore()); | 522 if (index >= size_without_output) { |
| 511 // If the index is past the existing stack items, return the output. | 523 // Materialize the result of the call instruction in this slot. |
| 512 if (index >= size_without_output) { | 524 AddTranslationForOperand( |
| 513 return {instr->OutputAt(index - size_without_output), | 525 translation, iter->instruction(), |
| 514 MachineType::AnyTagged()}; | 526 iter->instruction()->OutputAt(index - size_without_output), |
| 527 MachineType::AnyTagged()); |
| 528 continue; |
| 529 } |
| 530 break; |
| 515 } | 531 } |
| 516 break; | 532 case OutputFrameStateCombine::kPokeAt: |
| 533 // The result of the call should be placed at position |
| 534 // [index_from_top] in the stack (overwriting whatever was |
| 535 // previously there). |
| 536 size_t index_from_top = |
| 537 desc->GetSize(combine) - 1 - combine.GetOffsetToPokeAt(); |
| 538 if (index >= index_from_top && |
| 539 index < index_from_top + iter->instruction()->OutputCount()) { |
| 540 AddTranslationForOperand( |
| 541 translation, iter->instruction(), |
| 542 iter->instruction()->OutputAt(index - index_from_top), |
| 543 MachineType::AnyTagged()); |
| 544 iter->Advance(); // We do not use this input, but we need to |
| 545 // advace, as the input got replaced. |
| 546 continue; |
| 547 } |
| 548 break; |
| 517 } | 549 } |
| 518 case OutputFrameStateCombine::kPokeAt: | 550 StateValueDescriptor* value_desc = desc->GetStateValueDescriptor(); |
| 519 size_t index_from_top = | 551 TranslateStateValueDescriptor(&value_desc->fields()[index], translation, |
| 520 descriptor->GetSize(combine) - 1 - combine.GetOffsetToPokeAt(); | 552 iter); |
| 521 if (index >= index_from_top && | |
| 522 index < index_from_top + instr->OutputCount()) { | |
| 523 return {instr->OutputAt(index - index_from_top), | |
| 524 MachineType::AnyTagged()}; | |
| 525 } | |
| 526 break; | |
| 527 } | 553 } |
| 528 return {instr->InputAt(frame_state_offset + index), | |
| 529 descriptor->GetType(index)}; | |
| 530 } | 554 } |
| 531 | 555 |
| 532 } // namespace | |
| 533 | |
| 534 | 556 |
| 535 void CodeGenerator::BuildTranslationForFrameStateDescriptor( | 557 void CodeGenerator::BuildTranslationForFrameStateDescriptor( |
| 536 FrameStateDescriptor* descriptor, Instruction* instr, | 558 FrameStateDescriptor* descriptor, InstructionOperandIterator* iter, |
| 537 Translation* translation, size_t frame_state_offset, | 559 Translation* translation, OutputFrameStateCombine state_combine) { |
| 538 OutputFrameStateCombine state_combine) { | |
| 539 // Outer-most state must be added to translation first. | 560 // Outer-most state must be added to translation first. |
| 540 if (descriptor->outer_state() != nullptr) { | 561 if (descriptor->outer_state() != nullptr) { |
| 541 BuildTranslationForFrameStateDescriptor(descriptor->outer_state(), instr, | 562 BuildTranslationForFrameStateDescriptor(descriptor->outer_state(), iter, |
| 542 translation, frame_state_offset, | 563 translation, |
| 543 OutputFrameStateCombine::Ignore()); | 564 OutputFrameStateCombine::Ignore()); |
| 544 } | 565 } |
| 545 frame_state_offset += descriptor->outer_state()->GetTotalSize(); | |
| 546 | 566 |
| 547 Handle<SharedFunctionInfo> shared_info; | 567 Handle<SharedFunctionInfo> shared_info; |
| 548 if (!descriptor->shared_info().ToHandle(&shared_info)) { | 568 if (!descriptor->shared_info().ToHandle(&shared_info)) { |
| 549 if (!info()->has_shared_info()) return; // Stub with no SharedFunctionInfo. | 569 if (!info()->has_shared_info()) { |
| 570 return; // Stub with no SharedFunctionInfo. |
| 571 } |
| 550 shared_info = info()->shared_info(); | 572 shared_info = info()->shared_info(); |
| 551 } | 573 } |
| 552 int shared_info_id = DefineDeoptimizationLiteral(shared_info); | 574 int shared_info_id = DefineDeoptimizationLiteral(shared_info); |
| 553 | 575 |
| 554 switch (descriptor->type()) { | 576 switch (descriptor->type()) { |
| 555 case FrameStateType::kJavaScriptFunction: | 577 case FrameStateType::kJavaScriptFunction: |
| 556 translation->BeginJSFrame( | 578 translation->BeginJSFrame( |
| 557 descriptor->bailout_id(), shared_info_id, | 579 descriptor->bailout_id(), shared_info_id, |
| 558 static_cast<unsigned int>(descriptor->GetSize(state_combine) - | 580 static_cast<unsigned int>(descriptor->GetSize(state_combine) - |
| 559 (1 + descriptor->parameters_count()))); | 581 (1 + descriptor->parameters_count()))); |
| 560 break; | 582 break; |
| 561 case FrameStateType::kInterpretedFunction: | 583 case FrameStateType::kInterpretedFunction: |
| 562 translation->BeginInterpretedFrame( | 584 translation->BeginInterpretedFrame( |
| 563 descriptor->bailout_id(), shared_info_id, | 585 descriptor->bailout_id(), shared_info_id, |
| 564 static_cast<unsigned int>(descriptor->locals_count())); | 586 static_cast<unsigned int>(descriptor->locals_count())); |
| 565 break; | 587 break; |
| 566 case FrameStateType::kArgumentsAdaptor: | 588 case FrameStateType::kArgumentsAdaptor: |
| 567 translation->BeginArgumentsAdaptorFrame( | 589 translation->BeginArgumentsAdaptorFrame( |
| 568 shared_info_id, | 590 shared_info_id, |
| 569 static_cast<unsigned int>(descriptor->parameters_count())); | 591 static_cast<unsigned int>(descriptor->parameters_count())); |
| 570 break; | 592 break; |
| 571 case FrameStateType::kConstructStub: | 593 case FrameStateType::kConstructStub: |
| 572 translation->BeginConstructStubFrame( | 594 translation->BeginConstructStubFrame( |
| 573 shared_info_id, | 595 shared_info_id, |
| 574 static_cast<unsigned int>(descriptor->parameters_count())); | 596 static_cast<unsigned int>(descriptor->parameters_count())); |
| 575 break; | 597 break; |
| 576 } | 598 } |
| 577 | 599 |
| 578 for (size_t i = 0; i < descriptor->GetSize(state_combine); i++) { | 600 TranslateFrameStateDescriptorOperands(descriptor, iter, state_combine, |
| 579 OperandAndType op = TypedOperandForFrameState( | 601 translation); |
| 580 descriptor, instr, frame_state_offset, i, state_combine); | |
| 581 AddTranslationForOperand(translation, instr, op.operand, op.type); | |
| 582 } | |
| 583 } | 602 } |
| 584 | 603 |
| 585 | 604 |
| 586 int CodeGenerator::BuildTranslation(Instruction* instr, int pc_offset, | 605 int CodeGenerator::BuildTranslation(Instruction* instr, int pc_offset, |
| 587 size_t frame_state_offset, | 606 size_t frame_state_offset, |
| 588 OutputFrameStateCombine state_combine) { | 607 OutputFrameStateCombine state_combine) { |
| 589 FrameStateDescriptor* descriptor = | 608 FrameStateDescriptor* descriptor = |
| 590 GetFrameStateDescriptor(instr, frame_state_offset); | 609 GetFrameStateDescriptor(instr, frame_state_offset); |
| 591 frame_state_offset++; | 610 frame_state_offset++; |
| 592 | 611 |
| 593 Translation translation( | 612 Translation translation( |
| 594 &translations_, static_cast<int>(descriptor->GetFrameCount()), | 613 &translations_, static_cast<int>(descriptor->GetFrameCount()), |
| 595 static_cast<int>(descriptor->GetJSFrameCount()), zone()); | 614 static_cast<int>(descriptor->GetJSFrameCount()), zone()); |
| 596 BuildTranslationForFrameStateDescriptor(descriptor, instr, &translation, | 615 InstructionOperandIterator iter(instr, frame_state_offset); |
| 597 frame_state_offset, state_combine); | 616 BuildTranslationForFrameStateDescriptor(descriptor, &iter, &translation, |
| 617 state_combine); |
| 598 | 618 |
| 599 int deoptimization_id = static_cast<int>(deoptimization_states_.size()); | 619 int deoptimization_id = static_cast<int>(deoptimization_states_.size()); |
| 600 | 620 |
| 601 deoptimization_states_.push_back(new (zone()) DeoptimizationState( | 621 deoptimization_states_.push_back(new (zone()) DeoptimizationState( |
| 602 descriptor->bailout_id(), translation.index(), pc_offset)); | 622 descriptor->bailout_id(), translation.index(), pc_offset)); |
| 603 | 623 |
| 604 return deoptimization_id; | 624 return deoptimization_id; |
| 605 } | 625 } |
| 606 | 626 |
| 607 | 627 |
| (...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 708 : frame_(gen->frame()), masm_(gen->masm()), next_(gen->ools_) { | 728 : frame_(gen->frame()), masm_(gen->masm()), next_(gen->ools_) { |
| 709 gen->ools_ = this; | 729 gen->ools_ = this; |
| 710 } | 730 } |
| 711 | 731 |
| 712 | 732 |
| 713 OutOfLineCode::~OutOfLineCode() {} | 733 OutOfLineCode::~OutOfLineCode() {} |
| 714 | 734 |
| 715 } // namespace compiler | 735 } // namespace compiler |
| 716 } // namespace internal | 736 } // namespace internal |
| 717 } // namespace v8 | 737 } // namespace v8 |
| OLD | NEW |