| Index: runtime/vm/flow_graph_compiler_ia32.cc
|
| ===================================================================
|
| --- runtime/vm/flow_graph_compiler_ia32.cc (revision 8206)
|
| +++ runtime/vm/flow_graph_compiler_ia32.cc (working copy)
|
| @@ -29,37 +29,7 @@
|
| DECLARE_FLAG(bool, trace_functions);
|
|
|
|
|
| -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) {
|
| +void DeoptimizationStub::GenerateCode(FlowGraphCompilerShared* compiler) {
|
| Assembler* assem = compiler->assembler();
|
| #define __ assem->
|
| __ Comment("Deopt stub for id %d", deopt_id_);
|
| @@ -84,48 +54,20 @@
|
| const ParsedFunction& parsed_function,
|
| const GrowableArray<BlockEntryInstr*>& block_order,
|
| bool is_optimizing)
|
| - : FlowGraphVisitor(block_order),
|
| - assembler_(assembler),
|
| - parsed_function_(parsed_function),
|
| - block_info_(block_order.length()),
|
| - current_block_(NULL),
|
| - pc_descriptors_list_(NULL),
|
| - stackmap_builder_(NULL),
|
| - exception_handlers_list_(NULL),
|
| - deopt_stubs_(),
|
| - is_optimizing_(is_optimizing) {
|
| -}
|
| + : FlowGraphCompilerShared(assembler,
|
| + parsed_function,
|
| + block_order,
|
| + is_optimizing) {}
|
|
|
|
|
| -void FlowGraphCompiler::InitCompiler() {
|
| - pc_descriptors_list_ = new DescriptorList();
|
| - exception_handlers_list_ = new ExceptionHandlerList();
|
| - block_info_.Clear();
|
| - for (int i = 0; i < block_order_.length(); ++i) {
|
| - block_info_.Add(new BlockInfo());
|
| - }
|
| +void FlowGraphCompiler::FinalizeComments(const Code& code) {
|
| + code.set_comments(assembler()->GetCodeComments());
|
| }
|
|
|
|
|
| -FlowGraphCompiler::~FlowGraphCompiler() {
|
| - // BlockInfos are zone-allocated, so their destructors are not called.
|
| - // Verify the labels explicitly here.
|
| - for (int i = 0; i < block_info_.length(); ++i) {
|
| - ASSERT(!block_info_[i]->label.IsLinked());
|
| - ASSERT(!block_info_[i]->label.HasNear());
|
| - }
|
| -}
|
| -
|
| -
|
| -intptr_t FlowGraphCompiler::StackSize() const {
|
| - return parsed_function_.stack_local_count() +
|
| - parsed_function_.copied_parameter_count();
|
| -}
|
| -
|
| -
|
| void FlowGraphCompiler::Bailout(const char* reason) {
|
| const char* kFormat = "FlowGraphCompiler Bailout: %s %s.";
|
| - const char* function_name = parsed_function_.function().ToCString();
|
| + const char* function_name = parsed_function().function().ToCString();
|
| intptr_t len = OS::SNPrint(NULL, 0, kFormat, function_name, reason) + 1;
|
| char* chars = reinterpret_cast<char*>(
|
| Isolate::Current()->current_zone()->Allocate(len));
|
| @@ -136,25 +78,13 @@
|
| }
|
|
|
|
|
| -// Uses current pc position and try-index.
|
| -void FlowGraphCompiler::AddCurrentDescriptor(PcDescriptors::Kind kind,
|
| - intptr_t cid,
|
| - intptr_t token_index,
|
| - intptr_t try_index) {
|
| - pc_descriptors_list_->AddDescriptor(kind,
|
| - assembler_->CodeSize(),
|
| - cid,
|
| - token_index,
|
| - try_index);
|
| -}
|
| +#define __ assembler()->
|
|
|
| -#define __ assembler_->
|
| -
|
| void FlowGraphCompiler::IntrinsifyGetter() {
|
| // TOS: return address.
|
| // +1 : receiver.
|
| // Sequence node has one return node, its input is load field node.
|
| - const SequenceNode& sequence_node = *parsed_function_.node_sequence();
|
| + const SequenceNode& sequence_node = *parsed_function().node_sequence();
|
| ASSERT(sequence_node.length() == 1);
|
| ASSERT(sequence_node.NodeAt(0)->IsReturnNode());
|
| const ReturnNode& return_node = *sequence_node.NodeAt(0)->AsReturnNode();
|
| @@ -172,7 +102,7 @@
|
| // +1 : value
|
| // +2 : receiver.
|
| // Sequence node has one store node and one return NULL node.
|
| - const SequenceNode& sequence_node = *parsed_function_.node_sequence();
|
| + const SequenceNode& sequence_node = *parsed_function().node_sequence();
|
| ASSERT(sequence_node.length() == 2);
|
| ASSERT(sequence_node.NodeAt(0)->IsStoreInstanceFieldNode());
|
| ASSERT(sequence_node.NodeAt(1)->IsReturnNode());
|
| @@ -203,11 +133,11 @@
|
| // Intrinsification skips arguments checks, therefore disable if in checked
|
| // mode.
|
| if (FLAG_intrinsify && !FLAG_trace_functions && !FLAG_enable_type_checks) {
|
| - if ((parsed_function_.function().kind() == RawFunction::kImplicitGetter)) {
|
| + if ((parsed_function().function().kind() == RawFunction::kImplicitGetter)) {
|
| IntrinsifyGetter();
|
| return true;
|
| }
|
| - if ((parsed_function_.function().kind() == RawFunction::kImplicitSetter)) {
|
| + if ((parsed_function().function().kind() == RawFunction::kImplicitSetter)) {
|
| IntrinsifySetter();
|
| return true;
|
| }
|
| @@ -215,7 +145,7 @@
|
| // Even if an intrinsified version of the function was successfully
|
| // generated, it may fall through to the non-intrinsified method body.
|
| if (!FLAG_trace_functions) {
|
| - return Intrinsifier::Intrinsify(parsed_function_.function(), assembler_);
|
| + return Intrinsifier::Intrinsify(parsed_function().function(), assembler());
|
| }
|
| return false;
|
| }
|
| @@ -231,11 +161,11 @@
|
|
|
|
|
| void FlowGraphCompiler::CopyParameters() {
|
| - const Function& function = parsed_function_.function();
|
| - LocalScope* scope = parsed_function_.node_sequence()->scope();
|
| + const Function& function = parsed_function().function();
|
| + LocalScope* scope = parsed_function().node_sequence()->scope();
|
| const int num_fixed_params = function.num_fixed_parameters();
|
| const int num_opt_params = function.num_optional_parameters();
|
| - ASSERT(parsed_function_.first_parameter_index() ==
|
| + ASSERT(parsed_function().first_parameter_index() ==
|
| ParsedFunction::kFirstLocalSlotIndex);
|
| // Copy positional arguments.
|
| // Check that no fewer than num_fixed_params positional arguments are passed
|
| @@ -334,7 +264,7 @@
|
| __ Bind(&load_default_value);
|
| // Load EAX with default argument at pos.
|
| const Object& value = Object::ZoneHandle(
|
| - parsed_function_.default_parameter_values().At(
|
| + parsed_function().default_parameter_values().At(
|
| param_pos - num_fixed_params));
|
| __ LoadObject(EAX, value);
|
| __ Bind(&assign_optional_parameter);
|
| @@ -430,12 +360,12 @@
|
| return;
|
| }
|
| // Specialized version of entry code from CodeGenerator::GenerateEntryCode.
|
| - const Function& function = parsed_function_.function();
|
| + const Function& function = parsed_function().function();
|
|
|
| const int parameter_count = function.num_fixed_parameters();
|
| - const int num_copied_params = parsed_function_.copied_parameter_count();
|
| - const int local_count = parsed_function_.stack_local_count();
|
| - AssemblerMacros::EnterDartFrame(assembler_, (StackSize() * kWordSize));
|
| + const int num_copied_params = parsed_function().copied_parameter_count();
|
| + const int local_count = parsed_function().stack_local_count();
|
| + AssemblerMacros::EnterDartFrame(assembler(), (StackSize() * kWordSize));
|
| // We check the number of passed arguments when we have to copy them due to
|
| // the presence of optional named parameters.
|
| // No such checking code is generated if only fixed parameters are declared,
|
| @@ -471,7 +401,7 @@
|
| const Immediate raw_null =
|
| Immediate(reinterpret_cast<intptr_t>(Object::null()));
|
| __ movl(EAX, raw_null);
|
| - const int base = parsed_function_.first_stack_local_index();
|
| + const int base = parsed_function().first_stack_local_index();
|
| for (int i = 0; i < local_count; ++i) {
|
| // Subtract index i (locals lie at lower addresses than EBP).
|
| __ movl(Address(EBP, (base - i) * kWordSize), EAX);
|
| @@ -496,7 +426,7 @@
|
| // Second printing.
|
| OS::Print("Annotated ");
|
| }
|
| - AstPrinter::PrintFunctionScope(parsed_function_);
|
| + AstPrinter::PrintFunctionScope(parsed_function());
|
| }
|
|
|
| VisitBlocks();
|
| @@ -505,8 +435,8 @@
|
| GenerateDeferredCode();
|
| // Emit function patching code. This will be swapped with the first 5 bytes
|
| // at entry point.
|
| - pc_descriptors_list_->AddDescriptor(PcDescriptors::kPatchCode,
|
| - assembler_->CodeSize(),
|
| + pc_descriptors_list()->AddDescriptor(PcDescriptors::kPatchCode,
|
| + assembler()->CodeSize(),
|
| AstNode::kNoId,
|
| 0,
|
| -1);
|
| @@ -521,7 +451,7 @@
|
| intptr_t argument_count,
|
| const Array& argument_names,
|
| intptr_t checked_argument_count) {
|
| - ICData& ic_data = ICData::ZoneHandle(ICData::New(parsed_function_.function(),
|
| + ICData& ic_data = ICData::ZoneHandle(ICData::New(parsed_function().function(),
|
| function_name,
|
| cid,
|
| checked_argument_count));
|
| @@ -575,13 +505,6 @@
|
| }
|
|
|
|
|
| -void FlowGraphCompiler::GenerateDeferredCode() {
|
| - for (intptr_t i = 0; i < deopt_stubs_.length(); i++) {
|
| - deopt_stubs_[i]->GenerateCode(this);
|
| - }
|
| -}
|
| -
|
| -
|
| void FlowGraphCompiler::EmitComment(Instruction* instr) {
|
| char buffer[80];
|
| BufferFormatter f(buffer, sizeof(buffer));
|
| @@ -614,11 +537,12 @@
|
|
|
|
|
| void FlowGraphCompiler::VisitBlocks() {
|
| - for (intptr_t i = 0; i < block_order_.length(); ++i) {
|
| + for (intptr_t i = 0; i < block_order().length(); ++i) {
|
| __ Comment("B%d", i);
|
| // Compile the block entry.
|
| - current_block_ = block_order_[i];
|
| - Instruction* instr = current_block()->Accept(this);
|
| + set_current_block(block_order()[i]);
|
| + current_block()->PrepareEntry(this);
|
| + Instruction* instr = current_block()->StraightLineSuccessor();
|
| // Compile all successors until an exit, branch, or a block entry.
|
| while ((instr != NULL) && !instr->IsBlockEntry()) {
|
| if (FLAG_code_comments) EmitComment(instr);
|
| @@ -635,55 +559,14 @@
|
| if (successor != NULL) {
|
| // Block ended with a "goto". We can fall through if it is the
|
| // next block in the list. Otherwise, we need a jump.
|
| - if ((i == block_order_.length() - 1) ||
|
| - (block_order_[i + 1] != successor)) {
|
| - __ jmp(&block_info_[successor->postorder_number()]->label);
|
| + if ((i == block_order().length() - 1) ||
|
| + (block_order()[i + 1] != successor)) {
|
| + __ jmp(GetBlockLabel(successor));
|
| }
|
| }
|
| }
|
| }
|
|
|
| -
|
| -void FlowGraphCompiler::FinalizePcDescriptors(const Code& code) {
|
| - ASSERT(pc_descriptors_list_ != NULL);
|
| - const PcDescriptors& descriptors = PcDescriptors::Handle(
|
| - pc_descriptors_list_->FinalizePcDescriptors(code.EntryPoint()));
|
| - descriptors.Verify(parsed_function_.function().is_optimizable());
|
| - code.set_pc_descriptors(descriptors);
|
| -}
|
| -
|
| -
|
| -void FlowGraphCompiler::FinalizeStackmaps(const Code& code) {
|
| - if (stackmap_builder_ == NULL) {
|
| - // The unoptimizing compiler has no stack maps.
|
| - code.set_stackmaps(Array::Handle());
|
| - } else {
|
| - // Finalize the stack map array and add it to the code object.
|
| - code.set_stackmaps(
|
| - Array::Handle(stackmap_builder_->FinalizeStackmaps(code)));
|
| - }
|
| -}
|
| -
|
| -
|
| -void FlowGraphCompiler::FinalizeVarDescriptors(const Code& code) {
|
| - const LocalVarDescriptors& var_descs = LocalVarDescriptors::Handle(
|
| - parsed_function_.node_sequence()->scope()->GetVarDescriptors());
|
| - code.set_var_descriptors(var_descs);
|
| -}
|
| -
|
| -
|
| -void FlowGraphCompiler::FinalizeExceptionHandlers(const Code& code) {
|
| - ASSERT(exception_handlers_list_ != NULL);
|
| - const ExceptionHandlers& handlers = ExceptionHandlers::Handle(
|
| - exception_handlers_list_->FinalizeExceptionHandlers(code.EntryPoint()));
|
| - code.set_exception_handlers(handlers);
|
| -}
|
| -
|
| -
|
| -void FlowGraphCompiler::FinalizeComments(const Code& code) {
|
| - code.set_comments(assembler_->GetCodeComments());
|
| -}
|
| -
|
| #undef __
|
|
|
| } // namespace dart
|
|
|