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

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
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 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
75 try_index_); 75 try_index_);
76 #undef __ 76 #undef __
77 } 77 }
78 78
79 79
80 FlowGraphCompiler::FlowGraphCompiler( 80 FlowGraphCompiler::FlowGraphCompiler(
81 Assembler* assembler, 81 Assembler* assembler,
82 const ParsedFunction& parsed_function, 82 const ParsedFunction& parsed_function,
83 const GrowableArray<BlockEntryInstr*>& block_order, 83 const GrowableArray<BlockEntryInstr*>& block_order,
84 bool is_optimizing) 84 bool is_optimizing)
85 : FlowGraphVisitor(block_order), 85 : FlowGraphCompilerShared(parsed_function, block_order.length()),
86 assembler_(assembler), 86 assembler_(assembler),
87 parsed_function_(parsed_function), 87 block_order_(block_order),
88 block_info_(block_order.length()),
89 current_block_(NULL), 88 current_block_(NULL),
90 pc_descriptors_list_(NULL),
91 stackmap_builder_(NULL),
92 exception_handlers_list_(NULL),
93 deopt_stubs_(), 89 deopt_stubs_(),
94 is_optimizing_(is_optimizing) { 90 is_optimizing_(is_optimizing) {
95 } 91 }
96 92
97 93
98 FlowGraphCompiler::~FlowGraphCompiler() { 94 void FlowGraphCompiler::FinalizeComments(const Code& code) {
99 // BlockInfos are zone-allocated, so their destructors are not called. 95 code.set_comments(assembler_->GetCodeComments());
100 // Verify the labels explicitly here.
101 for (int i = 0; i < block_info_.length(); ++i) {
102 ASSERT(!block_info_[i]->label.IsLinked());
103 ASSERT(!block_info_[i]->label.HasNear());
104 }
105 }
106
107
108 void FlowGraphCompiler::InitCompiler() {
109 pc_descriptors_list_ = new DescriptorList();
110 exception_handlers_list_ = new ExceptionHandlerList();
111 block_info_.Clear();
112 for (int i = 0; i < block_order_.length(); ++i) {
113 block_info_.Add(new BlockInfo());
114 }
115 } 96 }
116 97
117 98
118 void FlowGraphCompiler::Bailout(const char* reason) { 99 void FlowGraphCompiler::Bailout(const char* reason) {
119 const char* kFormat = "FlowGraphCompiler Bailout: %s."; 100 const char* kFormat = "FlowGraphCompiler Bailout: %s.";
120 intptr_t len = OS::SNPrint(NULL, 0, kFormat, reason) + 1; 101 intptr_t len = OS::SNPrint(NULL, 0, kFormat, reason) + 1;
121 char* chars = reinterpret_cast<char*>( 102 char* chars = reinterpret_cast<char*>(
122 Isolate::Current()->current_zone()->Allocate(len)); 103 Isolate::Current()->current_zone()->Allocate(len));
123 OS::SNPrint(chars, len, kFormat, reason); 104 OS::SNPrint(chars, len, kFormat, reason);
124 const Error& error = Error::Handle( 105 const Error& error = Error::Handle(
125 LanguageError::New(String::Handle(String::New(chars)))); 106 LanguageError::New(String::Handle(String::New(chars))));
126 Isolate::Current()->long_jump_base()->Jump(1, error); 107 Isolate::Current()->long_jump_base()->Jump(1, error);
127 } 108 }
128 109
129 110
130 // Uses current pc position and try-index. 111 // Uses current pc position and try-index.
131 void FlowGraphCompiler::AddCurrentDescriptor(PcDescriptors::Kind kind, 112 void FlowGraphCompiler::AddCurrentDescriptor(PcDescriptors::Kind kind,
132 intptr_t cid, 113 intptr_t cid,
133 intptr_t token_index, 114 intptr_t token_index,
134 intptr_t try_index) { 115 intptr_t try_index) {
135 pc_descriptors_list_->AddDescriptor(kind, 116 pc_descriptors_list()->AddDescriptor(kind,
136 assembler_->CodeSize(), 117 assembler_->CodeSize(),
137 cid, 118 cid,
138 token_index, 119 token_index,
139 try_index); 120 try_index);
140 } 121 }
141 122
142 #define __ assembler_-> 123 #define __ assembler_->
143 124
144 void FlowGraphCompiler::IntrinsifyGetter() { 125 void FlowGraphCompiler::IntrinsifyGetter() {
145 // TOS: return address. 126 // TOS: return address.
146 // +1 : receiver. 127 // +1 : receiver.
147 // Sequence node has one return node, its input is load field node. 128 // Sequence node has one return node, its input is load field node.
148 const SequenceNode& sequence_node = *parsed_function_.node_sequence(); 129 const SequenceNode& sequence_node = *parsed_function().node_sequence();
149 ASSERT(sequence_node.length() == 1); 130 ASSERT(sequence_node.length() == 1);
150 ASSERT(sequence_node.NodeAt(0)->IsReturnNode()); 131 ASSERT(sequence_node.NodeAt(0)->IsReturnNode());
151 const ReturnNode& return_node = *sequence_node.NodeAt(0)->AsReturnNode(); 132 const ReturnNode& return_node = *sequence_node.NodeAt(0)->AsReturnNode();
152 ASSERT(return_node.value()->IsLoadInstanceFieldNode()); 133 ASSERT(return_node.value()->IsLoadInstanceFieldNode());
153 const LoadInstanceFieldNode& load_node = 134 const LoadInstanceFieldNode& load_node =
154 *return_node.value()->AsLoadInstanceFieldNode(); 135 *return_node.value()->AsLoadInstanceFieldNode();
155 __ movl(EAX, Address(ESP, 1 * kWordSize)); 136 __ movl(EAX, Address(ESP, 1 * kWordSize));
156 __ movl(EAX, FieldAddress(EAX, load_node.field().Offset())); 137 __ movl(EAX, FieldAddress(EAX, load_node.field().Offset()));
157 __ ret(); 138 __ ret();
158 } 139 }
159 140
160 141
161 void FlowGraphCompiler::IntrinsifySetter() { 142 void FlowGraphCompiler::IntrinsifySetter() {
162 // TOS: return address. 143 // TOS: return address.
163 // +1 : value 144 // +1 : value
164 // +2 : receiver. 145 // +2 : receiver.
165 // Sequence node has one store node and one return NULL node. 146 // Sequence node has one store node and one return NULL node.
166 const SequenceNode& sequence_node = *parsed_function_.node_sequence(); 147 const SequenceNode& sequence_node = *parsed_function().node_sequence();
167 ASSERT(sequence_node.length() == 2); 148 ASSERT(sequence_node.length() == 2);
168 ASSERT(sequence_node.NodeAt(0)->IsStoreInstanceFieldNode()); 149 ASSERT(sequence_node.NodeAt(0)->IsStoreInstanceFieldNode());
169 ASSERT(sequence_node.NodeAt(1)->IsReturnNode()); 150 ASSERT(sequence_node.NodeAt(1)->IsReturnNode());
170 const StoreInstanceFieldNode& store_node = 151 const StoreInstanceFieldNode& store_node =
171 *sequence_node.NodeAt(0)->AsStoreInstanceFieldNode(); 152 *sequence_node.NodeAt(0)->AsStoreInstanceFieldNode();
172 __ movl(EAX, Address(ESP, 2 * kWordSize)); // Receiver. 153 __ movl(EAX, Address(ESP, 2 * kWordSize)); // Receiver.
173 __ movl(EBX, Address(ESP, 1 * kWordSize)); // Value. 154 __ movl(EBX, Address(ESP, 1 * kWordSize)); // Value.
174 __ StoreIntoObject(EAX, FieldAddress(EAX, store_node.field().Offset()), EBX); 155 __ StoreIntoObject(EAX, FieldAddress(EAX, store_node.field().Offset()), EBX);
175 const Immediate raw_null = 156 const Immediate raw_null =
176 Immediate(reinterpret_cast<intptr_t>(Object::null())); 157 Immediate(reinterpret_cast<intptr_t>(Object::null()));
177 __ movl(EAX, raw_null); 158 __ movl(EAX, raw_null);
178 __ ret(); 159 __ ret();
179 } 160 }
180 161
181 162
182 intptr_t FlowGraphCompiler::StackSize() const { 163 intptr_t FlowGraphCompiler::StackSize() const {
183 return parsed_function_.stack_local_count() + 164 return parsed_function().stack_local_count() +
184 parsed_function_.copied_parameter_count(); 165 parsed_function().copied_parameter_count();
185 } 166 }
186 167
187 168
188 bool FlowGraphCompiler::CanOptimize() { 169 bool FlowGraphCompiler::CanOptimize() {
189 return 170 return
190 !FLAG_report_usage_count && 171 !FLAG_report_usage_count &&
191 (FLAG_optimization_counter_threshold >= 0) && 172 (FLAG_optimization_counter_threshold >= 0) &&
192 !Isolate::Current()->debugger()->IsActive(); 173 !Isolate::Current()->debugger()->IsActive();
193 } 174 }
194 175
195 176
196 // Returns 'true' if code generation for this function is complete, i.e., 177 // Returns 'true' if code generation for this function is complete, i.e.,
197 // no fall-through to regular code is needed. 178 // no fall-through to regular code is needed.
198 bool FlowGraphCompiler::TryIntrinsify() { 179 bool FlowGraphCompiler::TryIntrinsify() {
199 if (!CanOptimize()) return false; 180 if (!CanOptimize()) return false;
200 // Intrinsification skips arguments checks, therefore disable if in checked 181 // Intrinsification skips arguments checks, therefore disable if in checked
201 // mode. 182 // mode.
202 if (FLAG_intrinsify && !FLAG_trace_functions && !FLAG_enable_type_checks) { 183 if (FLAG_intrinsify && !FLAG_trace_functions && !FLAG_enable_type_checks) {
203 if ((parsed_function_.function().kind() == RawFunction::kImplicitGetter)) { 184 if ((parsed_function().function().kind() == RawFunction::kImplicitGetter)) {
204 IntrinsifyGetter(); 185 IntrinsifyGetter();
205 return true; 186 return true;
206 } 187 }
207 if ((parsed_function_.function().kind() == RawFunction::kImplicitSetter)) { 188 if ((parsed_function().function().kind() == RawFunction::kImplicitSetter)) {
208 IntrinsifySetter(); 189 IntrinsifySetter();
209 return true; 190 return true;
210 } 191 }
211 } 192 }
212 // Even if an intrinsified version of the function was successfully 193 // Even if an intrinsified version of the function was successfully
213 // generated, it may fall through to the non-intrinsified method body. 194 // generated, it may fall through to the non-intrinsified method body.
214 if (!FLAG_trace_functions) { 195 if (!FLAG_trace_functions) {
215 return Intrinsifier::Intrinsify(parsed_function_.function(), assembler_); 196 return Intrinsifier::Intrinsify(parsed_function().function(), assembler_);
216 } 197 }
217 return false; 198 return false;
218 } 199 }
219 200
220 201
221 void FlowGraphCompiler::GenerateCallRuntime(intptr_t cid, 202 void FlowGraphCompiler::GenerateCallRuntime(intptr_t cid,
222 intptr_t token_index, 203 intptr_t token_index,
223 intptr_t try_index, 204 intptr_t try_index,
224 const RuntimeEntry& entry) { 205 const RuntimeEntry& entry) {
225 __ CallRuntime(entry); 206 __ CallRuntime(entry);
226 AddCurrentDescriptor(PcDescriptors::kOther, cid, token_index, try_index); 207 AddCurrentDescriptor(PcDescriptors::kOther, cid, token_index, try_index);
227 } 208 }
228 209
229 210
230 void FlowGraphCompiler::CopyParameters() { 211 void FlowGraphCompiler::CopyParameters() {
231 Bailout("Copy Parameters"); 212 Bailout("Copy Parameters");
232 } 213 }
233 214
234 215
235 void FlowGraphCompiler::CompileGraph() { 216 void FlowGraphCompiler::CompileGraph() {
236 InitCompiler(); 217 InitCompiler();
237 if (TryIntrinsify()) { 218 if (TryIntrinsify()) {
238 __ int3(); 219 __ int3();
239 __ jmp(&StubCode::FixCallersTargetLabel()); 220 __ jmp(&StubCode::FixCallersTargetLabel());
240 return; 221 return;
241 } 222 }
242 // Specialized version of entry code from CodeGenerator::GenerateEntryCode. 223 // Specialized version of entry code from CodeGenerator::GenerateEntryCode.
243 const Function& function = parsed_function_.function(); 224 const Function& function = parsed_function().function();
244 225
245 const int parameter_count = function.num_fixed_parameters(); 226 const int parameter_count = function.num_fixed_parameters();
246 const int num_copied_params = parsed_function_.copied_parameter_count(); 227 const int num_copied_params = parsed_function().copied_parameter_count();
247 const int local_count = parsed_function_.stack_local_count(); 228 const int local_count = parsed_function().stack_local_count();
248 AssemblerMacros::EnterDartFrame(assembler_, (StackSize() * kWordSize)); 229 AssemblerMacros::EnterDartFrame(assembler_, (StackSize() * kWordSize));
249 // We check the number of passed arguments when we have to copy them due to 230 // We check the number of passed arguments when we have to copy them due to
250 // the presence of optional named parameters. 231 // the presence of optional named parameters.
251 // No such checking code is generated if only fixed parameters are declared, 232 // No such checking code is generated if only fixed parameters are declared,
252 // unless we are debug mode or unless we are compiling a closure. 233 // unless we are debug mode or unless we are compiling a closure.
253 if (num_copied_params == 0) { 234 if (num_copied_params == 0) {
254 #ifdef DEBUG 235 #ifdef DEBUG
255 const bool check_arguments = true; 236 const bool check_arguments = true;
256 #else 237 #else
257 const bool check_arguments = function.IsClosureFunction(); 238 const bool check_arguments = function.IsClosureFunction();
(...skipping 16 matching lines...) Expand all
274 __ Bind(&argc_in_range); 255 __ Bind(&argc_in_range);
275 } 256 }
276 } else { 257 } else {
277 CopyParameters(); 258 CopyParameters();
278 } 259 }
279 // Initialize (non-argument) stack allocated locals to null. 260 // Initialize (non-argument) stack allocated locals to null.
280 if (local_count > 0) { 261 if (local_count > 0) {
281 const Immediate raw_null = 262 const Immediate raw_null =
282 Immediate(reinterpret_cast<intptr_t>(Object::null())); 263 Immediate(reinterpret_cast<intptr_t>(Object::null()));
283 __ movl(EAX, raw_null); 264 __ movl(EAX, raw_null);
284 const int base = parsed_function_.first_stack_local_index(); 265 const int base = parsed_function().first_stack_local_index();
285 for (int i = 0; i < local_count; ++i) { 266 for (int i = 0; i < local_count; ++i) {
286 // Subtract index i (locals lie at lower addresses than EBP). 267 // Subtract index i (locals lie at lower addresses than EBP).
287 __ movl(Address(EBP, (base - i) * kWordSize), EAX); 268 __ movl(Address(EBP, (base - i) * kWordSize), EAX);
288 } 269 }
289 } 270 }
290 271
291 // Generate stack overflow check. 272 // Generate stack overflow check.
292 __ cmpl(ESP, 273 __ cmpl(ESP,
293 Address::Absolute(Isolate::Current()->stack_limit_address())); 274 Address::Absolute(Isolate::Current()->stack_limit_address()));
294 Label no_stack_overflow; 275 Label no_stack_overflow;
295 __ j(ABOVE, &no_stack_overflow, Assembler::kNearJump); 276 __ j(ABOVE, &no_stack_overflow, Assembler::kNearJump);
296 GenerateCallRuntime(AstNode::kNoId, 277 GenerateCallRuntime(AstNode::kNoId,
297 function.token_index(), 278 function.token_index(),
298 CatchClauseNode::kInvalidTryIndex, 279 CatchClauseNode::kInvalidTryIndex,
299 kStackOverflowRuntimeEntry); 280 kStackOverflowRuntimeEntry);
300 __ Bind(&no_stack_overflow); 281 __ Bind(&no_stack_overflow);
301 282
302 if (FLAG_print_scopes) { 283 if (FLAG_print_scopes) {
303 // Print the function scope (again) after generating the prologue in order 284 // Print the function scope (again) after generating the prologue in order
304 // to see annotations such as allocation indices of locals. 285 // to see annotations such as allocation indices of locals.
305 if (FLAG_print_ast) { 286 if (FLAG_print_ast) {
306 // Second printing. 287 // Second printing.
307 OS::Print("Annotated "); 288 OS::Print("Annotated ");
308 } 289 }
309 AstPrinter::PrintFunctionScope(parsed_function_); 290 AstPrinter::PrintFunctionScope(parsed_function());
310 } 291 }
311 292
312 VisitBlocks(); 293 VisitBlocks();
313 294
314 __ int3(); 295 __ int3();
315 GenerateDeferredCode(); 296 GenerateDeferredCode();
316 // Emit function patching code. This will be swapped with the first 5 bytes 297 // Emit function patching code. This will be swapped with the first 5 bytes
317 // at entry point. 298 // at entry point.
318 pc_descriptors_list_->AddDescriptor(PcDescriptors::kPatchCode, 299 pc_descriptors_list()->AddDescriptor(PcDescriptors::kPatchCode,
319 assembler_->CodeSize(), 300 assembler_->CodeSize(),
320 AstNode::kNoId, 301 AstNode::kNoId,
321 0, 302 0,
322 -1); 303 -1);
323 __ jmp(&StubCode::FixCallersTargetLabel()); 304 __ jmp(&StubCode::FixCallersTargetLabel());
324 } 305 }
325 306
326 307
327 void FlowGraphCompiler::EmitInstanceCall(intptr_t cid, 308 void FlowGraphCompiler::EmitInstanceCall(intptr_t cid,
328 intptr_t token_index, 309 intptr_t token_index,
329 intptr_t try_index, 310 intptr_t try_index,
330 const String& function_name, 311 const String& function_name,
331 intptr_t argument_count, 312 intptr_t argument_count,
332 const Array& argument_names, 313 const Array& argument_names,
333 intptr_t checked_argument_count) { 314 intptr_t checked_argument_count) {
334 ICData& ic_data = ICData::ZoneHandle(ICData::New(parsed_function_.function(), 315 ICData& ic_data = ICData::ZoneHandle(ICData::New(parsed_function().function(),
335 function_name, 316 function_name,
336 cid, 317 cid,
337 checked_argument_count)); 318 checked_argument_count));
338 const Array& arguments_descriptor = 319 const Array& arguments_descriptor =
339 CodeGenerator::ArgumentsDescriptor(argument_count, argument_names); 320 CodeGenerator::ArgumentsDescriptor(argument_count, argument_names);
340 __ LoadObject(ECX, ic_data); 321 __ LoadObject(ECX, ic_data);
341 __ LoadObject(EDX, arguments_descriptor); 322 __ LoadObject(EDX, arguments_descriptor);
342 323
343 uword label_address = 0; 324 uword label_address = 0;
344 switch (checked_argument_count) { 325 switch (checked_argument_count) {
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
421 __ popl(loc.reg()); 402 __ popl(loc.reg());
422 } 403 }
423 } 404 }
424 405
425 406
426 void FlowGraphCompiler::VisitBlocks() { 407 void FlowGraphCompiler::VisitBlocks() {
427 for (intptr_t i = 0; i < block_order_.length(); ++i) { 408 for (intptr_t i = 0; i < block_order_.length(); ++i) {
428 __ Comment("B%d", i); 409 __ Comment("B%d", i);
429 // Compile the block entry. 410 // Compile the block entry.
430 current_block_ = block_order_[i]; 411 current_block_ = block_order_[i];
431 Instruction* instr = current_block()->Accept(this); 412 current_block_->EmitNativeCode(this);
413 Instruction* instr = current_block_->StraightLineSuccessor();
432 // Compile all successors until an exit, branch, or a block entry. 414 // Compile all successors until an exit, branch, or a block entry.
433 while ((instr != NULL) && !instr->IsBlockEntry()) { 415 while ((instr != NULL) && !instr->IsBlockEntry()) {
434 if (FLAG_code_comments) EmitComment(instr); 416 if (FLAG_code_comments) EmitComment(instr);
435 if (instr->locs() == NULL) { 417 if (instr->locs() == NULL) {
436 BailoutOnInstruction(instr); 418 BailoutOnInstruction(instr);
437 } else { 419 } else {
438 EmitInstructionPrologue(instr); 420 EmitInstructionPrologue(instr);
439 instr->EmitNativeCode(this); 421 instr->EmitNativeCode(this);
440 instr = instr->StraightLineSuccessor(); 422 instr = instr->StraightLineSuccessor();
441 } 423 }
442 } 424 }
443 BlockEntryInstr* successor = 425 BlockEntryInstr* successor =
444 (instr == NULL) ? NULL : instr->AsBlockEntry(); 426 (instr == NULL) ? NULL : instr->AsBlockEntry();
445 if (successor != NULL) { 427 if (successor != NULL) {
446 // Block ended with a "goto". We can fall through if it is the 428 // Block ended with a "goto". We can fall through if it is the
447 // next block in the list. Otherwise, we need a jump. 429 // next block in the list. Otherwise, we need a jump.
448 if ((i == block_order_.length() - 1) || 430 if ((i == block_order_.length() - 1) ||
449 (block_order_[i + 1] != successor)) { 431 (block_order_[i + 1] != successor)) {
450 __ jmp(&block_info_[successor->postorder_number()]->label); 432 __ jmp(&block_info()[successor->postorder_number()]->label);
451 } 433 }
452 } 434 }
453 } 435 }
454 } 436 }
455 437
456
457 void FlowGraphCompiler::FinalizePcDescriptors(const Code& code) {
458 ASSERT(pc_descriptors_list_ != NULL);
459 const PcDescriptors& descriptors = PcDescriptors::Handle(
460 pc_descriptors_list_->FinalizePcDescriptors(code.EntryPoint()));
461 descriptors.Verify(parsed_function_.function().is_optimizable());
462 code.set_pc_descriptors(descriptors);
463 }
464
465
466 void FlowGraphCompiler::FinalizeStackmaps(const Code& code) {
467 if (stackmap_builder_ == NULL) {
468 // The unoptimizing compiler has no stack maps.
469 code.set_stackmaps(Array::Handle());
470 } else {
471 // Finalize the stack map array and add it to the code object.
472 code.set_stackmaps(
473 Array::Handle(stackmap_builder_->FinalizeStackmaps(code)));
474 }
475 }
476
477
478 void FlowGraphCompiler::FinalizeVarDescriptors(const Code& code) {
479 const LocalVarDescriptors& var_descs = LocalVarDescriptors::Handle(
480 parsed_function_.node_sequence()->scope()->GetVarDescriptors());
481 code.set_var_descriptors(var_descs);
482 }
483
484
485 void FlowGraphCompiler::FinalizeExceptionHandlers(const Code& code) {
486 ASSERT(exception_handlers_list_ != NULL);
487 const ExceptionHandlers& handlers = ExceptionHandlers::Handle(
488 exception_handlers_list_->FinalizeExceptionHandlers(code.EntryPoint()));
489 code.set_exception_handlers(handlers);
490 }
491
492
493 void FlowGraphCompiler::FinalizeComments(const Code& code) {
494 code.set_comments(assembler_->GetCodeComments());
495 }
496
497 #undef __ 438 #undef __
498 439
499 } // namespace dart 440 } // namespace dart
500 441
501 #endif // defined TARGET_ARCH_IA32 442 #endif // defined TARGET_ARCH_IA32
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698