Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(724)

Side by Side Diff: runtime/vm/flow_graph_compiler_ia32.cc

Issue 10447133: FlowGraphCompiler is not a visitor any longer. Start consolidating shared code between the x64 and … (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « runtime/vm/flow_graph_compiler_ia32.h ('k') | runtime/vm/flow_graph_compiler_shared.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_IA32. 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_IA32.
6 #if defined(TARGET_ARCH_IA32) 6 #if defined(TARGET_ARCH_IA32)
7 7
8 #include "vm/flow_graph_compiler.h" 8 #include "vm/flow_graph_compiler.h"
9 9
10 #include "vm/ast_printer.h" 10 #include "vm/ast_printer.h"
(...skipping 11 matching lines...) Expand all
22 DECLARE_FLAG(bool, compiler_stats); 22 DECLARE_FLAG(bool, compiler_stats);
23 DECLARE_FLAG(bool, enable_type_checks); 23 DECLARE_FLAG(bool, enable_type_checks);
24 DECLARE_FLAG(bool, intrinsify); 24 DECLARE_FLAG(bool, intrinsify);
25 DECLARE_FLAG(int, optimization_counter_threshold); 25 DECLARE_FLAG(int, optimization_counter_threshold);
26 DECLARE_FLAG(bool, print_ast); 26 DECLARE_FLAG(bool, print_ast);
27 DECLARE_FLAG(bool, print_scopes); 27 DECLARE_FLAG(bool, print_scopes);
28 DECLARE_FLAG(bool, report_usage_count); 28 DECLARE_FLAG(bool, report_usage_count);
29 DECLARE_FLAG(bool, trace_functions); 29 DECLARE_FLAG(bool, trace_functions);
30 30
31 31
32 class DeoptimizationStub : public ZoneAllocated { 32 void DeoptimizationStub::GenerateCode(FlowGraphCompilerShared* compiler) {
33 public:
34 DeoptimizationStub(intptr_t deopt_id,
35 intptr_t deopt_token_index,
36 intptr_t try_index,
37 DeoptReasonId reason)
38 : deopt_id_(deopt_id),
39 deopt_token_index_(deopt_token_index),
40 try_index_(try_index),
41 reason_(reason),
42 registers_(2),
43 entry_label_() {}
44
45 void Push(Register reg) { registers_.Add(reg); }
46 Label* entry_label() { return &entry_label_; }
47
48 void GenerateCode(FlowGraphCompiler* compiler);
49
50 private:
51 const intptr_t deopt_id_;
52 const intptr_t deopt_token_index_;
53 const intptr_t try_index_;
54 const DeoptReasonId reason_;
55 GrowableArray<Register> registers_;
56 Label entry_label_;
57
58 DISALLOW_COPY_AND_ASSIGN(DeoptimizationStub);
59 };
60
61
62 void DeoptimizationStub::GenerateCode(FlowGraphCompiler* compiler) {
63 Assembler* assem = compiler->assembler(); 33 Assembler* assem = compiler->assembler();
64 #define __ assem-> 34 #define __ assem->
65 __ Comment("Deopt stub for id %d", deopt_id_); 35 __ Comment("Deopt stub for id %d", deopt_id_);
66 __ Bind(entry_label()); 36 __ Bind(entry_label());
67 for (intptr_t i = 0; i < registers_.length(); i++) { 37 for (intptr_t i = 0; i < registers_.length(); i++) {
68 if (registers_[i] != kNoRegister) { 38 if (registers_[i] != kNoRegister) {
69 __ pushl(registers_[i]); 39 __ pushl(registers_[i]);
70 } 40 }
71 } 41 }
72 __ movl(EAX, Immediate(Smi::RawValue(reason_))); 42 __ movl(EAX, Immediate(Smi::RawValue(reason_)));
73 __ call(&StubCode::DeoptimizeLabel()); 43 __ call(&StubCode::DeoptimizeLabel());
74 compiler->AddCurrentDescriptor(PcDescriptors::kOther, 44 compiler->AddCurrentDescriptor(PcDescriptors::kOther,
75 deopt_id_, 45 deopt_id_,
76 deopt_token_index_, 46 deopt_token_index_,
77 try_index_); 47 try_index_);
78 #undef __ 48 #undef __
79 } 49 }
80 50
81 51
82 FlowGraphCompiler::FlowGraphCompiler( 52 FlowGraphCompiler::FlowGraphCompiler(
83 Assembler* assembler, 53 Assembler* assembler,
84 const ParsedFunction& parsed_function, 54 const ParsedFunction& parsed_function,
85 const GrowableArray<BlockEntryInstr*>& block_order, 55 const GrowableArray<BlockEntryInstr*>& block_order,
86 bool is_optimizing) 56 bool is_optimizing)
87 : FlowGraphVisitor(block_order), 57 : FlowGraphCompilerShared(assembler,
88 assembler_(assembler), 58 parsed_function,
89 parsed_function_(parsed_function), 59 block_order,
90 block_info_(block_order.length()), 60 is_optimizing) {}
91 current_block_(NULL),
92 pc_descriptors_list_(NULL),
93 stackmap_builder_(NULL),
94 exception_handlers_list_(NULL),
95 deopt_stubs_(),
96 is_optimizing_(is_optimizing) {
97 }
98 61
99 62
100 void FlowGraphCompiler::InitCompiler() { 63 void FlowGraphCompiler::FinalizeComments(const Code& code) {
101 pc_descriptors_list_ = new DescriptorList(); 64 code.set_comments(assembler()->GetCodeComments());
102 exception_handlers_list_ = new ExceptionHandlerList();
103 block_info_.Clear();
104 for (int i = 0; i < block_order_.length(); ++i) {
105 block_info_.Add(new BlockInfo());
106 }
107 }
108
109
110 FlowGraphCompiler::~FlowGraphCompiler() {
111 // BlockInfos are zone-allocated, so their destructors are not called.
112 // Verify the labels explicitly here.
113 for (int i = 0; i < block_info_.length(); ++i) {
114 ASSERT(!block_info_[i]->label.IsLinked());
115 ASSERT(!block_info_[i]->label.HasNear());
116 }
117 }
118
119
120 intptr_t FlowGraphCompiler::StackSize() const {
121 return parsed_function_.stack_local_count() +
122 parsed_function_.copied_parameter_count();
123 } 65 }
124 66
125 67
126 void FlowGraphCompiler::Bailout(const char* reason) { 68 void FlowGraphCompiler::Bailout(const char* reason) {
127 const char* kFormat = "FlowGraphCompiler Bailout: %s %s."; 69 const char* kFormat = "FlowGraphCompiler Bailout: %s %s.";
128 const char* function_name = parsed_function_.function().ToCString(); 70 const char* function_name = parsed_function().function().ToCString();
129 intptr_t len = OS::SNPrint(NULL, 0, kFormat, function_name, reason) + 1; 71 intptr_t len = OS::SNPrint(NULL, 0, kFormat, function_name, reason) + 1;
130 char* chars = reinterpret_cast<char*>( 72 char* chars = reinterpret_cast<char*>(
131 Isolate::Current()->current_zone()->Allocate(len)); 73 Isolate::Current()->current_zone()->Allocate(len));
132 OS::SNPrint(chars, len, kFormat, function_name, reason); 74 OS::SNPrint(chars, len, kFormat, function_name, reason);
133 const Error& error = Error::Handle( 75 const Error& error = Error::Handle(
134 LanguageError::New(String::Handle(String::New(chars)))); 76 LanguageError::New(String::Handle(String::New(chars))));
135 Isolate::Current()->long_jump_base()->Jump(1, error); 77 Isolate::Current()->long_jump_base()->Jump(1, error);
136 } 78 }
137 79
138 80
139 // Uses current pc position and try-index. 81 #define __ assembler()->
140 void FlowGraphCompiler::AddCurrentDescriptor(PcDescriptors::Kind kind,
141 intptr_t cid,
142 intptr_t token_index,
143 intptr_t try_index) {
144 pc_descriptors_list_->AddDescriptor(kind,
145 assembler_->CodeSize(),
146 cid,
147 token_index,
148 try_index);
149 }
150
151 #define __ assembler_->
152 82
153 void FlowGraphCompiler::IntrinsifyGetter() { 83 void FlowGraphCompiler::IntrinsifyGetter() {
154 // TOS: return address. 84 // TOS: return address.
155 // +1 : receiver. 85 // +1 : receiver.
156 // Sequence node has one return node, its input is load field node. 86 // Sequence node has one return node, its input is load field node.
157 const SequenceNode& sequence_node = *parsed_function_.node_sequence(); 87 const SequenceNode& sequence_node = *parsed_function().node_sequence();
158 ASSERT(sequence_node.length() == 1); 88 ASSERT(sequence_node.length() == 1);
159 ASSERT(sequence_node.NodeAt(0)->IsReturnNode()); 89 ASSERT(sequence_node.NodeAt(0)->IsReturnNode());
160 const ReturnNode& return_node = *sequence_node.NodeAt(0)->AsReturnNode(); 90 const ReturnNode& return_node = *sequence_node.NodeAt(0)->AsReturnNode();
161 ASSERT(return_node.value()->IsLoadInstanceFieldNode()); 91 ASSERT(return_node.value()->IsLoadInstanceFieldNode());
162 const LoadInstanceFieldNode& load_node = 92 const LoadInstanceFieldNode& load_node =
163 *return_node.value()->AsLoadInstanceFieldNode(); 93 *return_node.value()->AsLoadInstanceFieldNode();
164 __ movl(EAX, Address(ESP, 1 * kWordSize)); 94 __ movl(EAX, Address(ESP, 1 * kWordSize));
165 __ movl(EAX, FieldAddress(EAX, load_node.field().Offset())); 95 __ movl(EAX, FieldAddress(EAX, load_node.field().Offset()));
166 __ ret(); 96 __ ret();
167 } 97 }
168 98
169 99
170 void FlowGraphCompiler::IntrinsifySetter() { 100 void FlowGraphCompiler::IntrinsifySetter() {
171 // TOS: return address. 101 // TOS: return address.
172 // +1 : value 102 // +1 : value
173 // +2 : receiver. 103 // +2 : receiver.
174 // Sequence node has one store node and one return NULL node. 104 // Sequence node has one store node and one return NULL node.
175 const SequenceNode& sequence_node = *parsed_function_.node_sequence(); 105 const SequenceNode& sequence_node = *parsed_function().node_sequence();
176 ASSERT(sequence_node.length() == 2); 106 ASSERT(sequence_node.length() == 2);
177 ASSERT(sequence_node.NodeAt(0)->IsStoreInstanceFieldNode()); 107 ASSERT(sequence_node.NodeAt(0)->IsStoreInstanceFieldNode());
178 ASSERT(sequence_node.NodeAt(1)->IsReturnNode()); 108 ASSERT(sequence_node.NodeAt(1)->IsReturnNode());
179 const StoreInstanceFieldNode& store_node = 109 const StoreInstanceFieldNode& store_node =
180 *sequence_node.NodeAt(0)->AsStoreInstanceFieldNode(); 110 *sequence_node.NodeAt(0)->AsStoreInstanceFieldNode();
181 __ movl(EAX, Address(ESP, 2 * kWordSize)); // Receiver. 111 __ movl(EAX, Address(ESP, 2 * kWordSize)); // Receiver.
182 __ movl(EBX, Address(ESP, 1 * kWordSize)); // Value. 112 __ movl(EBX, Address(ESP, 1 * kWordSize)); // Value.
183 __ StoreIntoObject(EAX, FieldAddress(EAX, store_node.field().Offset()), EBX); 113 __ StoreIntoObject(EAX, FieldAddress(EAX, store_node.field().Offset()), EBX);
184 const Immediate raw_null = 114 const Immediate raw_null =
185 Immediate(reinterpret_cast<intptr_t>(Object::null())); 115 Immediate(reinterpret_cast<intptr_t>(Object::null()));
(...skipping 10 matching lines...) Expand all
196 } 126 }
197 127
198 128
199 // Returns 'true' if code generation for this function is complete, i.e., 129 // Returns 'true' if code generation for this function is complete, i.e.,
200 // no fall-through to regular code is needed. 130 // no fall-through to regular code is needed.
201 bool FlowGraphCompiler::TryIntrinsify() { 131 bool FlowGraphCompiler::TryIntrinsify() {
202 if (!CanOptimize()) return false; 132 if (!CanOptimize()) return false;
203 // Intrinsification skips arguments checks, therefore disable if in checked 133 // Intrinsification skips arguments checks, therefore disable if in checked
204 // mode. 134 // mode.
205 if (FLAG_intrinsify && !FLAG_trace_functions && !FLAG_enable_type_checks) { 135 if (FLAG_intrinsify && !FLAG_trace_functions && !FLAG_enable_type_checks) {
206 if ((parsed_function_.function().kind() == RawFunction::kImplicitGetter)) { 136 if ((parsed_function().function().kind() == RawFunction::kImplicitGetter)) {
207 IntrinsifyGetter(); 137 IntrinsifyGetter();
208 return true; 138 return true;
209 } 139 }
210 if ((parsed_function_.function().kind() == RawFunction::kImplicitSetter)) { 140 if ((parsed_function().function().kind() == RawFunction::kImplicitSetter)) {
211 IntrinsifySetter(); 141 IntrinsifySetter();
212 return true; 142 return true;
213 } 143 }
214 } 144 }
215 // Even if an intrinsified version of the function was successfully 145 // Even if an intrinsified version of the function was successfully
216 // generated, it may fall through to the non-intrinsified method body. 146 // generated, it may fall through to the non-intrinsified method body.
217 if (!FLAG_trace_functions) { 147 if (!FLAG_trace_functions) {
218 return Intrinsifier::Intrinsify(parsed_function_.function(), assembler_); 148 return Intrinsifier::Intrinsify(parsed_function().function(), assembler());
219 } 149 }
220 return false; 150 return false;
221 } 151 }
222 152
223 153
224 void FlowGraphCompiler::GenerateCallRuntime(intptr_t cid, 154 void FlowGraphCompiler::GenerateCallRuntime(intptr_t cid,
225 intptr_t token_index, 155 intptr_t token_index,
226 intptr_t try_index, 156 intptr_t try_index,
227 const RuntimeEntry& entry) { 157 const RuntimeEntry& entry) {
228 __ CallRuntime(entry); 158 __ CallRuntime(entry);
229 AddCurrentDescriptor(PcDescriptors::kOther, cid, token_index, try_index); 159 AddCurrentDescriptor(PcDescriptors::kOther, cid, token_index, try_index);
230 } 160 }
231 161
232 162
233 void FlowGraphCompiler::CopyParameters() { 163 void FlowGraphCompiler::CopyParameters() {
234 const Function& function = parsed_function_.function(); 164 const Function& function = parsed_function().function();
235 LocalScope* scope = parsed_function_.node_sequence()->scope(); 165 LocalScope* scope = parsed_function().node_sequence()->scope();
236 const int num_fixed_params = function.num_fixed_parameters(); 166 const int num_fixed_params = function.num_fixed_parameters();
237 const int num_opt_params = function.num_optional_parameters(); 167 const int num_opt_params = function.num_optional_parameters();
238 ASSERT(parsed_function_.first_parameter_index() == 168 ASSERT(parsed_function().first_parameter_index() ==
239 ParsedFunction::kFirstLocalSlotIndex); 169 ParsedFunction::kFirstLocalSlotIndex);
240 // Copy positional arguments. 170 // Copy positional arguments.
241 // Check that no fewer than num_fixed_params positional arguments are passed 171 // Check that no fewer than num_fixed_params positional arguments are passed
242 // in and that no more than num_params arguments are passed in. 172 // in and that no more than num_params arguments are passed in.
243 // Passed argument i at fp[1 + argc - i] 173 // Passed argument i at fp[1 + argc - i]
244 // copied to fp[ParsedFunction::kFirstLocalSlotIndex - i]. 174 // copied to fp[ParsedFunction::kFirstLocalSlotIndex - i].
245 const int num_params = num_fixed_params + num_opt_params; 175 const int num_params = num_fixed_params + num_opt_params;
246 176
247 // Total number of args is the first Smi in args descriptor array (EDX). 177 // Total number of args is the first Smi in args descriptor array (EDX).
248 __ movl(EBX, FieldAddress(EDX, Array::data_offset())); 178 __ movl(EBX, FieldAddress(EDX, Array::data_offset()));
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
327 // fp[1 + argc - arg_pos]. 257 // fp[1 + argc - arg_pos].
328 __ movl(EAX, Address(EDI, kWordSize)); // EAX is arg_pos as Smi. 258 __ movl(EAX, Address(EDI, kWordSize)); // EAX is arg_pos as Smi.
329 __ addl(EDI, Immediate(2 * kWordSize)); // Point to next name/pos pair. 259 __ addl(EDI, Immediate(2 * kWordSize)); // Point to next name/pos pair.
330 __ negl(EAX); 260 __ negl(EAX);
331 Address argument_addr(EBX, EAX, TIMES_2, 0); // EAX is a negative Smi. 261 Address argument_addr(EBX, EAX, TIMES_2, 0); // EAX is a negative Smi.
332 __ movl(EAX, argument_addr); 262 __ movl(EAX, argument_addr);
333 __ jmp(&assign_optional_parameter, Assembler::kNearJump); 263 __ jmp(&assign_optional_parameter, Assembler::kNearJump);
334 __ Bind(&load_default_value); 264 __ Bind(&load_default_value);
335 // Load EAX with default argument at pos. 265 // Load EAX with default argument at pos.
336 const Object& value = Object::ZoneHandle( 266 const Object& value = Object::ZoneHandle(
337 parsed_function_.default_parameter_values().At( 267 parsed_function().default_parameter_values().At(
338 param_pos - num_fixed_params)); 268 param_pos - num_fixed_params));
339 __ LoadObject(EAX, value); 269 __ LoadObject(EAX, value);
340 __ Bind(&assign_optional_parameter); 270 __ Bind(&assign_optional_parameter);
341 // Assign EAX to fp[ParsedFunction::kFirstLocalSlotIndex - param_pos]. 271 // Assign EAX to fp[ParsedFunction::kFirstLocalSlotIndex - param_pos].
342 // We do not use the final allocation index of the variable here, i.e. 272 // We do not use the final allocation index of the variable here, i.e.
343 // scope->VariableAt(i)->index(), because captured variables still need 273 // scope->VariableAt(i)->index(), because captured variables still need
344 // to be copied to the context that is not yet allocated. 274 // to be copied to the context that is not yet allocated.
345 const Address param_addr( 275 const Address param_addr(
346 EBP, (ParsedFunction::kFirstLocalSlotIndex - param_pos) * kWordSize); 276 EBP, (ParsedFunction::kFirstLocalSlotIndex - param_pos) * kWordSize);
347 __ movl(param_addr, EAX); 277 __ movl(param_addr, EAX);
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
423 353
424 354
425 void FlowGraphCompiler::CompileGraph() { 355 void FlowGraphCompiler::CompileGraph() {
426 InitCompiler(); 356 InitCompiler();
427 if (TryIntrinsify()) { 357 if (TryIntrinsify()) {
428 __ int3(); 358 __ int3();
429 __ jmp(&StubCode::FixCallersTargetLabel()); 359 __ jmp(&StubCode::FixCallersTargetLabel());
430 return; 360 return;
431 } 361 }
432 // Specialized version of entry code from CodeGenerator::GenerateEntryCode. 362 // Specialized version of entry code from CodeGenerator::GenerateEntryCode.
433 const Function& function = parsed_function_.function(); 363 const Function& function = parsed_function().function();
434 364
435 const int parameter_count = function.num_fixed_parameters(); 365 const int parameter_count = function.num_fixed_parameters();
436 const int num_copied_params = parsed_function_.copied_parameter_count(); 366 const int num_copied_params = parsed_function().copied_parameter_count();
437 const int local_count = parsed_function_.stack_local_count(); 367 const int local_count = parsed_function().stack_local_count();
438 AssemblerMacros::EnterDartFrame(assembler_, (StackSize() * kWordSize)); 368 AssemblerMacros::EnterDartFrame(assembler(), (StackSize() * kWordSize));
439 // We check the number of passed arguments when we have to copy them due to 369 // We check the number of passed arguments when we have to copy them due to
440 // the presence of optional named parameters. 370 // the presence of optional named parameters.
441 // No such checking code is generated if only fixed parameters are declared, 371 // No such checking code is generated if only fixed parameters are declared,
442 // unless we are debug mode or unless we are compiling a closure. 372 // unless we are debug mode or unless we are compiling a closure.
443 if (num_copied_params == 0) { 373 if (num_copied_params == 0) {
444 #ifdef DEBUG 374 #ifdef DEBUG
445 const bool check_arguments = true; 375 const bool check_arguments = true;
446 #else 376 #else
447 const bool check_arguments = function.IsClosureFunction(); 377 const bool check_arguments = function.IsClosureFunction();
448 #endif 378 #endif
(...skipping 15 matching lines...) Expand all
464 __ Bind(&argc_in_range); 394 __ Bind(&argc_in_range);
465 } 395 }
466 } else { 396 } else {
467 CopyParameters(); 397 CopyParameters();
468 } 398 }
469 // Initialize (non-argument) stack allocated locals to null. 399 // Initialize (non-argument) stack allocated locals to null.
470 if (local_count > 0) { 400 if (local_count > 0) {
471 const Immediate raw_null = 401 const Immediate raw_null =
472 Immediate(reinterpret_cast<intptr_t>(Object::null())); 402 Immediate(reinterpret_cast<intptr_t>(Object::null()));
473 __ movl(EAX, raw_null); 403 __ movl(EAX, raw_null);
474 const int base = parsed_function_.first_stack_local_index(); 404 const int base = parsed_function().first_stack_local_index();
475 for (int i = 0; i < local_count; ++i) { 405 for (int i = 0; i < local_count; ++i) {
476 // Subtract index i (locals lie at lower addresses than EBP). 406 // Subtract index i (locals lie at lower addresses than EBP).
477 __ movl(Address(EBP, (base - i) * kWordSize), EAX); 407 __ movl(Address(EBP, (base - i) * kWordSize), EAX);
478 } 408 }
479 } 409 }
480 410
481 // Generate stack overflow check. 411 // Generate stack overflow check.
482 __ cmpl(ESP, 412 __ cmpl(ESP,
483 Address::Absolute(Isolate::Current()->stack_limit_address())); 413 Address::Absolute(Isolate::Current()->stack_limit_address()));
484 Label no_stack_overflow; 414 Label no_stack_overflow;
485 __ j(ABOVE, &no_stack_overflow, Assembler::kNearJump); 415 __ j(ABOVE, &no_stack_overflow, Assembler::kNearJump);
486 GenerateCallRuntime(AstNode::kNoId, 416 GenerateCallRuntime(AstNode::kNoId,
487 function.token_index(), 417 function.token_index(),
488 CatchClauseNode::kInvalidTryIndex, 418 CatchClauseNode::kInvalidTryIndex,
489 kStackOverflowRuntimeEntry); 419 kStackOverflowRuntimeEntry);
490 __ Bind(&no_stack_overflow); 420 __ Bind(&no_stack_overflow);
491 421
492 if (FLAG_print_scopes) { 422 if (FLAG_print_scopes) {
493 // Print the function scope (again) after generating the prologue in order 423 // Print the function scope (again) after generating the prologue in order
494 // to see annotations such as allocation indices of locals. 424 // to see annotations such as allocation indices of locals.
495 if (FLAG_print_ast) { 425 if (FLAG_print_ast) {
496 // Second printing. 426 // Second printing.
497 OS::Print("Annotated "); 427 OS::Print("Annotated ");
498 } 428 }
499 AstPrinter::PrintFunctionScope(parsed_function_); 429 AstPrinter::PrintFunctionScope(parsed_function());
500 } 430 }
501 431
502 VisitBlocks(); 432 VisitBlocks();
503 433
504 __ int3(); 434 __ int3();
505 GenerateDeferredCode(); 435 GenerateDeferredCode();
506 // Emit function patching code. This will be swapped with the first 5 bytes 436 // Emit function patching code. This will be swapped with the first 5 bytes
507 // at entry point. 437 // at entry point.
508 pc_descriptors_list_->AddDescriptor(PcDescriptors::kPatchCode, 438 pc_descriptors_list()->AddDescriptor(PcDescriptors::kPatchCode,
509 assembler_->CodeSize(), 439 assembler()->CodeSize(),
510 AstNode::kNoId, 440 AstNode::kNoId,
511 0, 441 0,
512 -1); 442 -1);
513 __ jmp(&StubCode::FixCallersTargetLabel()); 443 __ jmp(&StubCode::FixCallersTargetLabel());
514 } 444 }
515 445
516 446
517 void FlowGraphCompiler::EmitInstanceCall(intptr_t cid, 447 void FlowGraphCompiler::EmitInstanceCall(intptr_t cid,
518 intptr_t token_index, 448 intptr_t token_index,
519 intptr_t try_index, 449 intptr_t try_index,
520 const String& function_name, 450 const String& function_name,
521 intptr_t argument_count, 451 intptr_t argument_count,
522 const Array& argument_names, 452 const Array& argument_names,
523 intptr_t checked_argument_count) { 453 intptr_t checked_argument_count) {
524 ICData& ic_data = ICData::ZoneHandle(ICData::New(parsed_function_.function(), 454 ICData& ic_data = ICData::ZoneHandle(ICData::New(parsed_function().function(),
525 function_name, 455 function_name,
526 cid, 456 cid,
527 checked_argument_count)); 457 checked_argument_count));
528 const Array& arguments_descriptor = 458 const Array& arguments_descriptor =
529 CodeGenerator::ArgumentsDescriptor(argument_count, argument_names); 459 CodeGenerator::ArgumentsDescriptor(argument_count, argument_names);
530 __ LoadObject(ECX, ic_data); 460 __ LoadObject(ECX, ic_data);
531 __ LoadObject(EDX, arguments_descriptor); 461 __ LoadObject(EDX, arguments_descriptor);
532 462
533 uword label_address = 0; 463 uword label_address = 0;
534 switch (checked_argument_count) { 464 switch (checked_argument_count) {
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
568 498
569 void FlowGraphCompiler::GenerateCall(intptr_t token_index, 499 void FlowGraphCompiler::GenerateCall(intptr_t token_index,
570 intptr_t try_index, 500 intptr_t try_index,
571 const ExternalLabel* label, 501 const ExternalLabel* label,
572 PcDescriptors::Kind kind) { 502 PcDescriptors::Kind kind) {
573 __ call(label); 503 __ call(label);
574 AddCurrentDescriptor(kind, AstNode::kNoId, token_index, try_index); 504 AddCurrentDescriptor(kind, AstNode::kNoId, token_index, try_index);
575 } 505 }
576 506
577 507
578 void FlowGraphCompiler::GenerateDeferredCode() {
579 for (intptr_t i = 0; i < deopt_stubs_.length(); i++) {
580 deopt_stubs_[i]->GenerateCode(this);
581 }
582 }
583
584
585 void FlowGraphCompiler::EmitComment(Instruction* instr) { 508 void FlowGraphCompiler::EmitComment(Instruction* instr) {
586 char buffer[80]; 509 char buffer[80];
587 BufferFormatter f(buffer, sizeof(buffer)); 510 BufferFormatter f(buffer, sizeof(buffer));
588 instr->PrintTo(&f); 511 instr->PrintTo(&f);
589 __ Comment("@%d: %s", instr->cid(), buffer); 512 __ Comment("@%d: %s", instr->cid(), buffer);
590 } 513 }
591 514
592 515
593 void FlowGraphCompiler::BailoutOnInstruction(Instruction* instr) { 516 void FlowGraphCompiler::BailoutOnInstruction(Instruction* instr) {
594 char buffer[80]; 517 char buffer[80];
(...skipping 12 matching lines...) Expand all
607 // Load instruction inputs into allocated registers. 530 // Load instruction inputs into allocated registers.
608 for (intptr_t i = locs->input_count() - 1; i >= 0; i--) { 531 for (intptr_t i = locs->input_count() - 1; i >= 0; i--) {
609 Location loc = locs->in(i); 532 Location loc = locs->in(i);
610 ASSERT(loc.kind() == Location::kRegister); 533 ASSERT(loc.kind() == Location::kRegister);
611 __ popl(loc.reg()); 534 __ popl(loc.reg());
612 } 535 }
613 } 536 }
614 537
615 538
616 void FlowGraphCompiler::VisitBlocks() { 539 void FlowGraphCompiler::VisitBlocks() {
617 for (intptr_t i = 0; i < block_order_.length(); ++i) { 540 for (intptr_t i = 0; i < block_order().length(); ++i) {
618 __ Comment("B%d", i); 541 __ Comment("B%d", i);
619 // Compile the block entry. 542 // Compile the block entry.
620 current_block_ = block_order_[i]; 543 set_current_block(block_order()[i]);
621 Instruction* instr = current_block()->Accept(this); 544 current_block()->PrepareEntry(this);
545 Instruction* instr = current_block()->StraightLineSuccessor();
622 // Compile all successors until an exit, branch, or a block entry. 546 // Compile all successors until an exit, branch, or a block entry.
623 while ((instr != NULL) && !instr->IsBlockEntry()) { 547 while ((instr != NULL) && !instr->IsBlockEntry()) {
624 if (FLAG_code_comments) EmitComment(instr); 548 if (FLAG_code_comments) EmitComment(instr);
625 if (instr->locs() == NULL) { 549 if (instr->locs() == NULL) {
626 BailoutOnInstruction(instr); 550 BailoutOnInstruction(instr);
627 } else { 551 } else {
628 EmitInstructionPrologue(instr); 552 EmitInstructionPrologue(instr);
629 instr->EmitNativeCode(this); 553 instr->EmitNativeCode(this);
630 instr = instr->StraightLineSuccessor(); 554 instr = instr->StraightLineSuccessor();
631 } 555 }
632 } 556 }
633 BlockEntryInstr* successor = 557 BlockEntryInstr* successor =
634 (instr == NULL) ? NULL : instr->AsBlockEntry(); 558 (instr == NULL) ? NULL : instr->AsBlockEntry();
635 if (successor != NULL) { 559 if (successor != NULL) {
636 // Block ended with a "goto". We can fall through if it is the 560 // Block ended with a "goto". We can fall through if it is the
637 // next block in the list. Otherwise, we need a jump. 561 // next block in the list. Otherwise, we need a jump.
638 if ((i == block_order_.length() - 1) || 562 if ((i == block_order().length() - 1) ||
639 (block_order_[i + 1] != successor)) { 563 (block_order()[i + 1] != successor)) {
640 __ jmp(&block_info_[successor->postorder_number()]->label); 564 __ jmp(GetBlockLabel(successor));
641 } 565 }
642 } 566 }
643 } 567 }
644 } 568 }
645 569
646
647 void FlowGraphCompiler::FinalizePcDescriptors(const Code& code) {
648 ASSERT(pc_descriptors_list_ != NULL);
649 const PcDescriptors& descriptors = PcDescriptors::Handle(
650 pc_descriptors_list_->FinalizePcDescriptors(code.EntryPoint()));
651 descriptors.Verify(parsed_function_.function().is_optimizable());
652 code.set_pc_descriptors(descriptors);
653 }
654
655
656 void FlowGraphCompiler::FinalizeStackmaps(const Code& code) {
657 if (stackmap_builder_ == NULL) {
658 // The unoptimizing compiler has no stack maps.
659 code.set_stackmaps(Array::Handle());
660 } else {
661 // Finalize the stack map array and add it to the code object.
662 code.set_stackmaps(
663 Array::Handle(stackmap_builder_->FinalizeStackmaps(code)));
664 }
665 }
666
667
668 void FlowGraphCompiler::FinalizeVarDescriptors(const Code& code) {
669 const LocalVarDescriptors& var_descs = LocalVarDescriptors::Handle(
670 parsed_function_.node_sequence()->scope()->GetVarDescriptors());
671 code.set_var_descriptors(var_descs);
672 }
673
674
675 void FlowGraphCompiler::FinalizeExceptionHandlers(const Code& code) {
676 ASSERT(exception_handlers_list_ != NULL);
677 const ExceptionHandlers& handlers = ExceptionHandlers::Handle(
678 exception_handlers_list_->FinalizeExceptionHandlers(code.EntryPoint()));
679 code.set_exception_handlers(handlers);
680 }
681
682
683 void FlowGraphCompiler::FinalizeComments(const Code& code) {
684 code.set_comments(assembler_->GetCodeComments());
685 }
686
687 #undef __ 570 #undef __
688 571
689 } // namespace dart 572 } // namespace dart
690 573
691 #endif // defined TARGET_ARCH_IA32 574 #endif // defined TARGET_ARCH_IA32
OLDNEW
« no previous file with comments | « runtime/vm/flow_graph_compiler_ia32.h ('k') | runtime/vm/flow_graph_compiler_shared.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698