| Index: runtime/vm/flow_graph_compiler_x64.cc
|
| ===================================================================
|
| --- runtime/vm/flow_graph_compiler_x64.cc (revision 7951)
|
| +++ runtime/vm/flow_graph_compiler_x64.cc (working copy)
|
| @@ -32,7 +32,54 @@
|
| DECLARE_FLAG(bool, report_usage_count);
|
| DECLARE_FLAG(bool, code_comments);
|
|
|
| +class DeoptimizationStub : public ZoneAllocated {
|
| + public:
|
| + DeoptimizationStub(intptr_t deopt_id,
|
| + intptr_t deopt_token_index,
|
| + intptr_t try_index,
|
| + DeoptReasonId reason)
|
| + : deopt_id_(deopt_id),
|
| + deopt_token_index_(deopt_token_index),
|
| + try_index_(try_index),
|
| + reason_(reason),
|
| + registers_(2),
|
| + entry_label_() {}
|
|
|
| + void Push(Register reg) { registers_.Add(reg); }
|
| + Label* entry_label() { return &entry_label_; }
|
| +
|
| + void GenerateCode(FlowGraphCompiler* compiler);
|
| +
|
| + private:
|
| + const intptr_t deopt_id_;
|
| + const intptr_t deopt_token_index_;
|
| + const intptr_t try_index_;
|
| + const DeoptReasonId reason_;
|
| + GrowableArray<Register> registers_;
|
| + Label entry_label_;
|
| +
|
| + DISALLOW_COPY_AND_ASSIGN(DeoptimizationStub);
|
| +};
|
| +
|
| +
|
| +void DeoptimizationStub::GenerateCode(FlowGraphCompiler* compiler) {
|
| + Assembler* assem = compiler->assembler();
|
| +#define __ assem->
|
| + __ Comment("Deopt stub for id %d", deopt_id_);
|
| + __ Bind(entry_label());
|
| + for (intptr_t i = 0; i < registers_.length(); i++) {
|
| + __ pushq(registers_[i]);
|
| + }
|
| + __ movq(RAX, Immediate(Smi::RawValue(reason_)));
|
| + __ call(&StubCode::DeoptimizeLabel());
|
| + compiler->AddCurrentDescriptor(PcDescriptors::kOther,
|
| + deopt_id_,
|
| + deopt_token_index_,
|
| + try_index_);
|
| +#undef __
|
| +}
|
| +
|
| +
|
| FlowGraphCompiler::FlowGraphCompiler(
|
| Assembler* assembler,
|
| const ParsedFunction& parsed_function,
|
| @@ -45,6 +92,7 @@
|
| current_block_(NULL),
|
| pc_descriptors_list_(NULL),
|
| exception_handlers_list_(NULL),
|
| + deopt_stubs_(),
|
| is_optimizing_(is_optimizing) {
|
| }
|
|
|
| @@ -1296,6 +1344,11 @@
|
| }
|
|
|
|
|
| +void FlowGraphCompiler::VisitBinaryOp(BinaryOpComp* comp) {
|
| + UNIMPLEMENTED();
|
| +}
|
| +
|
| +
|
| void FlowGraphCompiler::EmitInstructionPrologue(Instruction* instr) {
|
| LocationSummary* locs = instr->locs();
|
| ASSERT(locs != NULL);
|
| @@ -1836,6 +1889,7 @@
|
| VisitBlocks();
|
|
|
| __ int3();
|
| + GenerateDeferredCode();
|
| // Emit function patching code. This will be swapped with the first 13 bytes
|
| // at entry point.
|
| pc_descriptors_list_->AddDescriptor(PcDescriptors::kPatchCode,
|
| @@ -1847,6 +1901,13 @@
|
| }
|
|
|
|
|
| +void FlowGraphCompiler::GenerateDeferredCode() {
|
| + for (intptr_t i = 0; i < deopt_stubs_.length(); i++) {
|
| + deopt_stubs_[i]->GenerateCode(this);
|
| + }
|
| +}
|
| +
|
| +
|
| // Infrastructure copied from class CodeGenerator.
|
| void FlowGraphCompiler::GenerateCall(intptr_t token_index,
|
| intptr_t try_index,
|
| @@ -1879,6 +1940,21 @@
|
| }
|
|
|
|
|
| +Label* FlowGraphCompiler::AddDeoptStub(intptr_t deopt_id,
|
| + intptr_t deopt_token_index,
|
| + intptr_t try_index,
|
| + DeoptReasonId reason,
|
| + Register reg1,
|
| + Register reg2) {
|
| + DeoptimizationStub* stub =
|
| + new DeoptimizationStub(deopt_id, deopt_token_index, try_index, reason);
|
| + stub->Push(reg1);
|
| + stub->Push(reg2);
|
| + deopt_stubs_.Add(stub);
|
| + return stub->entry_label();
|
| +}
|
| +
|
| +
|
| void FlowGraphCompiler::FinalizePcDescriptors(const Code& code) {
|
| ASSERT(pc_descriptors_list_ != NULL);
|
| const PcDescriptors& descriptors = PcDescriptors::Handle(
|
| @@ -1913,6 +1989,7 @@
|
| code.set_comments(assembler_->GetCodeComments());
|
| }
|
|
|
| +#undef __
|
|
|
| } // namespace dart
|
|
|
|
|