| OLD | NEW |
| 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/interpreter-assembler.h" | 5 #include "src/compiler/interpreter-assembler.h" |
| 6 | 6 |
| 7 #include <ostream> | 7 #include <ostream> |
| 8 | 8 |
| 9 #include "src/code-factory.h" | 9 #include "src/code-factory.h" |
| 10 #include "src/compiler/graph.h" | 10 #include "src/compiler/graph.h" |
| (...skipping 14 matching lines...) Expand all Loading... |
| 25 namespace compiler { | 25 namespace compiler { |
| 26 | 26 |
| 27 | 27 |
| 28 InterpreterAssembler::InterpreterAssembler(Isolate* isolate, Zone* zone, | 28 InterpreterAssembler::InterpreterAssembler(Isolate* isolate, Zone* zone, |
| 29 interpreter::Bytecode bytecode) | 29 interpreter::Bytecode bytecode) |
| 30 : bytecode_(bytecode), | 30 : bytecode_(bytecode), |
| 31 raw_assembler_(new RawMachineAssembler( | 31 raw_assembler_(new RawMachineAssembler( |
| 32 isolate, new (zone) Graph(zone), | 32 isolate, new (zone) Graph(zone), |
| 33 Linkage::GetInterpreterDispatchDescriptor(zone), kMachPtr, | 33 Linkage::GetInterpreterDispatchDescriptor(zone), kMachPtr, |
| 34 InstructionSelector::SupportedMachineOperatorFlags())), | 34 InstructionSelector::SupportedMachineOperatorFlags())), |
| 35 end_nodes_(zone), | |
| 36 accumulator_( | 35 accumulator_( |
| 37 raw_assembler_->Parameter(Linkage::kInterpreterAccumulatorParameter)), | 36 raw_assembler_->Parameter(Linkage::kInterpreterAccumulatorParameter)), |
| 38 context_( | 37 context_( |
| 39 raw_assembler_->Parameter(Linkage::kInterpreterContextParameter)), | 38 raw_assembler_->Parameter(Linkage::kInterpreterContextParameter)), |
| 40 code_generated_(false) {} | 39 code_generated_(false) {} |
| 41 | 40 |
| 42 | 41 |
| 43 InterpreterAssembler::~InterpreterAssembler() {} | 42 InterpreterAssembler::~InterpreterAssembler() {} |
| 44 | 43 |
| 45 | 44 |
| 46 Handle<Code> InterpreterAssembler::GenerateCode() { | 45 Handle<Code> InterpreterAssembler::GenerateCode() { |
| 47 DCHECK(!code_generated_); | 46 DCHECK(!code_generated_); |
| 48 | 47 |
| 49 End(); | 48 // Disallow empty handlers that never return. |
| 49 DCHECK_NE(0, graph()->end()->InputCount()); |
| 50 | 50 |
| 51 const char* bytecode_name = interpreter::Bytecodes::ToString(bytecode_); | 51 const char* bytecode_name = interpreter::Bytecodes::ToString(bytecode_); |
| 52 Schedule* schedule = raw_assembler_->Export(); | 52 Schedule* schedule = raw_assembler_->Export(); |
| 53 // TODO(rmcilroy): use a non-testing code generator. | 53 // TODO(rmcilroy): use a non-testing code generator. |
| 54 Handle<Code> code = Pipeline::GenerateCodeForCodeStub( | 54 Handle<Code> code = Pipeline::GenerateCodeForCodeStub( |
| 55 isolate(), raw_assembler_->call_descriptor(), graph(), schedule, | 55 isolate(), raw_assembler_->call_descriptor(), graph(), schedule, |
| 56 Code::STUB, bytecode_name); | 56 Code::STUB, bytecode_name); |
| 57 | 57 |
| 58 #ifdef ENABLE_DISASSEMBLER | 58 #ifdef ENABLE_DISASSEMBLER |
| 59 if (FLAG_trace_ignition_codegen) { | 59 if (FLAG_trace_ignition_codegen) { |
| (...skipping 460 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 520 STATIC_ASSERT(2 == Linkage::kInterpreterBytecodeOffsetParameter); | 520 STATIC_ASSERT(2 == Linkage::kInterpreterBytecodeOffsetParameter); |
| 521 STATIC_ASSERT(3 == Linkage::kInterpreterBytecodeArrayParameter); | 521 STATIC_ASSERT(3 == Linkage::kInterpreterBytecodeArrayParameter); |
| 522 STATIC_ASSERT(4 == Linkage::kInterpreterDispatchTableParameter); | 522 STATIC_ASSERT(4 == Linkage::kInterpreterDispatchTableParameter); |
| 523 STATIC_ASSERT(5 == Linkage::kInterpreterContextParameter); | 523 STATIC_ASSERT(5 == Linkage::kInterpreterContextParameter); |
| 524 Node* args[] = { GetAccumulator(), | 524 Node* args[] = { GetAccumulator(), |
| 525 RegisterFileRawPointer(), | 525 RegisterFileRawPointer(), |
| 526 BytecodeOffset(), | 526 BytecodeOffset(), |
| 527 BytecodeArrayTaggedPointer(), | 527 BytecodeArrayTaggedPointer(), |
| 528 DispatchTableRawPointer(), | 528 DispatchTableRawPointer(), |
| 529 GetContext() }; | 529 GetContext() }; |
| 530 Node* tail_call = raw_assembler_->TailCallN( | 530 raw_assembler_->TailCallN(call_descriptor(), exit_trampoline_code_object, |
| 531 call_descriptor(), exit_trampoline_code_object, args); | 531 args); |
| 532 // This should always be the end node. | |
| 533 AddEndInput(tail_call); | |
| 534 } | 532 } |
| 535 | 533 |
| 536 | 534 |
| 537 Node* InterpreterAssembler::Advance(int delta) { | 535 Node* InterpreterAssembler::Advance(int delta) { |
| 538 return IntPtrAdd(BytecodeOffset(), Int32Constant(delta)); | 536 return IntPtrAdd(BytecodeOffset(), Int32Constant(delta)); |
| 539 } | 537 } |
| 540 | 538 |
| 541 | 539 |
| 542 Node* InterpreterAssembler::Advance(Node* delta) { | 540 Node* InterpreterAssembler::Advance(Node* delta) { |
| 543 return raw_assembler_->IntPtrAdd(BytecodeOffset(), delta); | 541 return raw_assembler_->IntPtrAdd(BytecodeOffset(), delta); |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 580 STATIC_ASSERT(2 == Linkage::kInterpreterBytecodeOffsetParameter); | 578 STATIC_ASSERT(2 == Linkage::kInterpreterBytecodeOffsetParameter); |
| 581 STATIC_ASSERT(3 == Linkage::kInterpreterBytecodeArrayParameter); | 579 STATIC_ASSERT(3 == Linkage::kInterpreterBytecodeArrayParameter); |
| 582 STATIC_ASSERT(4 == Linkage::kInterpreterDispatchTableParameter); | 580 STATIC_ASSERT(4 == Linkage::kInterpreterDispatchTableParameter); |
| 583 STATIC_ASSERT(5 == Linkage::kInterpreterContextParameter); | 581 STATIC_ASSERT(5 == Linkage::kInterpreterContextParameter); |
| 584 Node* args[] = { GetAccumulator(), | 582 Node* args[] = { GetAccumulator(), |
| 585 RegisterFileRawPointer(), | 583 RegisterFileRawPointer(), |
| 586 new_bytecode_offset, | 584 new_bytecode_offset, |
| 587 BytecodeArrayTaggedPointer(), | 585 BytecodeArrayTaggedPointer(), |
| 588 DispatchTableRawPointer(), | 586 DispatchTableRawPointer(), |
| 589 GetContext() }; | 587 GetContext() }; |
| 590 Node* tail_call = | 588 raw_assembler_->TailCallN(call_descriptor(), target_code_object, args); |
| 591 raw_assembler_->TailCallN(call_descriptor(), target_code_object, args); | |
| 592 // This should always be the end node. | |
| 593 AddEndInput(tail_call); | |
| 594 } | 589 } |
| 595 | 590 |
| 596 | 591 |
| 597 void InterpreterAssembler::Abort(BailoutReason bailout_reason) { | 592 void InterpreterAssembler::Abort(BailoutReason bailout_reason) { |
| 598 Node* abort_id = SmiTag(Int32Constant(bailout_reason)); | 593 Node* abort_id = SmiTag(Int32Constant(bailout_reason)); |
| 599 CallRuntime(Runtime::kAbort, abort_id); | 594 CallRuntime(Runtime::kAbort, abort_id); |
| 600 Return(); | 595 Return(); |
| 601 } | 596 } |
| 602 | 597 |
| 603 | 598 |
| 604 void InterpreterAssembler::AbortIfWordNotEqual(Node* lhs, Node* rhs, | 599 void InterpreterAssembler::AbortIfWordNotEqual(Node* lhs, Node* rhs, |
| 605 BailoutReason bailout_reason) { | 600 BailoutReason bailout_reason) { |
| 606 RawMachineLabel match, no_match; | 601 RawMachineLabel match, no_match; |
| 607 Node* condition = raw_assembler_->WordEqual(lhs, rhs); | 602 Node* condition = raw_assembler_->WordEqual(lhs, rhs); |
| 608 raw_assembler_->Branch(condition, &match, &no_match); | 603 raw_assembler_->Branch(condition, &match, &no_match); |
| 609 raw_assembler_->Bind(&no_match); | 604 raw_assembler_->Bind(&no_match); |
| 610 Abort(bailout_reason); | 605 Abort(bailout_reason); |
| 611 raw_assembler_->Bind(&match); | 606 raw_assembler_->Bind(&match); |
| 612 } | 607 } |
| 613 | 608 |
| 614 | 609 |
| 615 void InterpreterAssembler::AddEndInput(Node* input) { | |
| 616 DCHECK_NOT_NULL(input); | |
| 617 end_nodes_.push_back(input); | |
| 618 } | |
| 619 | |
| 620 | |
| 621 void InterpreterAssembler::End() { | |
| 622 DCHECK(!end_nodes_.empty()); | |
| 623 int end_count = static_cast<int>(end_nodes_.size()); | |
| 624 Node* end = graph()->NewNode(raw_assembler_->common()->End(end_count), | |
| 625 end_count, &end_nodes_[0]); | |
| 626 graph()->SetEnd(end); | |
| 627 } | |
| 628 | |
| 629 | |
| 630 // static | 610 // static |
| 631 bool InterpreterAssembler::TargetSupportsUnalignedAccess() { | 611 bool InterpreterAssembler::TargetSupportsUnalignedAccess() { |
| 632 #if V8_TARGET_ARCH_MIPS || V8_TARGET_ARCH_MIPS64 | 612 #if V8_TARGET_ARCH_MIPS || V8_TARGET_ARCH_MIPS64 |
| 633 return false; | 613 return false; |
| 634 #elif V8_TARGET_ARCH_ARM || V8_TARGET_ARCH_ARM64 || V8_TARGET_ARCH_PPC | 614 #elif V8_TARGET_ARCH_ARM || V8_TARGET_ARCH_ARM64 || V8_TARGET_ARCH_PPC |
| 635 return CpuFeatures::IsSupported(UNALIGNED_ACCESSES); | 615 return CpuFeatures::IsSupported(UNALIGNED_ACCESSES); |
| 636 #elif V8_TARGET_ARCH_IA32 || V8_TARGET_ARCH_X64 || V8_TARGET_ARCH_X87 | 616 #elif V8_TARGET_ARCH_IA32 || V8_TARGET_ARCH_X64 || V8_TARGET_ARCH_X87 |
| 637 return true; | 617 return true; |
| 638 #else | 618 #else |
| 639 #error "Unknown Architecture" | 619 #error "Unknown Architecture" |
| (...skipping 12 matching lines...) Expand all Loading... |
| 652 return raw_assembler_->call_descriptor(); | 632 return raw_assembler_->call_descriptor(); |
| 653 } | 633 } |
| 654 | 634 |
| 655 | 635 |
| 656 Zone* InterpreterAssembler::zone() { return raw_assembler_->zone(); } | 636 Zone* InterpreterAssembler::zone() { return raw_assembler_->zone(); } |
| 657 | 637 |
| 658 | 638 |
| 659 } // namespace compiler | 639 } // namespace compiler |
| 660 } // namespace internal | 640 } // namespace internal |
| 661 } // namespace v8 | 641 } // namespace v8 |
| OLD | NEW |