OLD | NEW |
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_XXX. | 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_XXX. |
6 | 6 |
7 #include "vm/flow_graph_compiler.h" | 7 #include "vm/flow_graph_compiler.h" |
8 | 8 |
9 #include "vm/dart_entry.h" | 9 #include "vm/dart_entry.h" |
10 #include "vm/debugger.h" | 10 #include "vm/debugger.h" |
(...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
153 if (instr->IsParallelMove()) { | 153 if (instr->IsParallelMove()) { |
154 parallel_move_resolver_.EmitNativeCode(instr->AsParallelMove()); | 154 parallel_move_resolver_.EmitNativeCode(instr->AsParallelMove()); |
155 } else { | 155 } else { |
156 ASSERT(instr->locs() != NULL); | 156 ASSERT(instr->locs() != NULL); |
157 EmitInstructionPrologue(instr); | 157 EmitInstructionPrologue(instr); |
158 pending_deoptimization_env_ = instr->env(); | 158 pending_deoptimization_env_ = instr->env(); |
159 instr->EmitNativeCode(this); | 159 instr->EmitNativeCode(this); |
160 } | 160 } |
161 } | 161 } |
162 } | 162 } |
| 163 set_current_block(NULL); |
163 } | 164 } |
164 | 165 |
165 | 166 |
166 void FlowGraphCompiler::Bailout(const char* reason) { | 167 void FlowGraphCompiler::Bailout(const char* reason) { |
167 const char* kFormat = "FlowGraphCompiler Bailout: %s %s."; | 168 const char* kFormat = "FlowGraphCompiler Bailout: %s %s."; |
168 const char* function_name = parsed_function().function().ToCString(); | 169 const char* function_name = parsed_function().function().ToCString(); |
169 intptr_t len = OS::SNPrint(NULL, 0, kFormat, function_name, reason) + 1; | 170 intptr_t len = OS::SNPrint(NULL, 0, kFormat, function_name, reason) + 1; |
170 char* chars = Isolate::Current()->current_zone()->Alloc<char>(len); | 171 char* chars = Isolate::Current()->current_zone()->Alloc<char>(len); |
171 OS::SNPrint(chars, len, kFormat, function_name, reason); | 172 OS::SNPrint(chars, len, kFormat, function_name, reason); |
172 const Error& error = Error::Handle( | 173 const Error& error = Error::Handle( |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
216 | 217 |
217 void FlowGraphCompiler::AddExceptionHandler(intptr_t try_index, | 218 void FlowGraphCompiler::AddExceptionHandler(intptr_t try_index, |
218 intptr_t pc_offset) { | 219 intptr_t pc_offset) { |
219 exception_handlers_list_->AddHandler(try_index, pc_offset); | 220 exception_handlers_list_->AddHandler(try_index, pc_offset); |
220 } | 221 } |
221 | 222 |
222 | 223 |
223 // Uses current pc position and try-index. | 224 // Uses current pc position and try-index. |
224 void FlowGraphCompiler::AddCurrentDescriptor(PcDescriptors::Kind kind, | 225 void FlowGraphCompiler::AddCurrentDescriptor(PcDescriptors::Kind kind, |
225 intptr_t deopt_id, | 226 intptr_t deopt_id, |
226 intptr_t token_pos, | 227 intptr_t token_pos) { |
227 intptr_t try_index) { | |
228 pc_descriptors_list()->AddDescriptor(kind, | 228 pc_descriptors_list()->AddDescriptor(kind, |
229 assembler()->CodeSize(), | 229 assembler()->CodeSize(), |
230 deopt_id, | 230 deopt_id, |
231 token_pos, | 231 token_pos, |
232 try_index); | 232 CurrentTryIndex()); |
233 } | 233 } |
234 | 234 |
235 | 235 |
236 void FlowGraphCompiler::AddDeoptIndexAtCall(intptr_t deopt_id, | 236 void FlowGraphCompiler::AddDeoptIndexAtCall(intptr_t deopt_id, |
237 intptr_t token_pos) { | 237 intptr_t token_pos) { |
238 // TODO(srdjan): Temporary use deopt stubs to maintain deopt-indexes. | 238 // TODO(srdjan): Temporary use deopt stubs to maintain deopt-indexes. |
239 // kDeoptAtCall will not emit code, but will only generate deoptimization | 239 // kDeoptAtCall will not emit code, but will only generate deoptimization |
240 // information. | 240 // information. |
241 const intptr_t deopt_index = deopt_stubs_.length(); | 241 const intptr_t deopt_index = deopt_stubs_.length(); |
242 AddDeoptStub(deopt_id, kDeoptAtCall); | 242 AddDeoptStub(deopt_id, kDeoptAtCall); |
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
363 if (!FLAG_trace_functions) { | 363 if (!FLAG_trace_functions) { |
364 return Intrinsifier::Intrinsify(parsed_function().function(), assembler()); | 364 return Intrinsifier::Intrinsify(parsed_function().function(), assembler()); |
365 } | 365 } |
366 return false; | 366 return false; |
367 } | 367 } |
368 | 368 |
369 | 369 |
370 void FlowGraphCompiler::GenerateInstanceCall( | 370 void FlowGraphCompiler::GenerateInstanceCall( |
371 intptr_t deopt_id, | 371 intptr_t deopt_id, |
372 intptr_t token_pos, | 372 intptr_t token_pos, |
373 intptr_t try_index, | |
374 const String& function_name, | 373 const String& function_name, |
375 intptr_t argument_count, | 374 intptr_t argument_count, |
376 const Array& argument_names, | 375 const Array& argument_names, |
377 intptr_t checked_argument_count, | 376 intptr_t checked_argument_count, |
378 LocationSummary* locs) { | 377 LocationSummary* locs) { |
379 ASSERT(!IsLeaf()); | 378 ASSERT(!IsLeaf()); |
380 ICData& ic_data = | 379 ICData& ic_data = |
381 ICData::ZoneHandle(ICData::New(parsed_function().function(), | 380 ICData::ZoneHandle(ICData::New(parsed_function().function(), |
382 function_name, | 381 function_name, |
383 deopt_id, | 382 deopt_id, |
384 checked_argument_count)); | 383 checked_argument_count)); |
385 const Array& arguments_descriptor = | 384 const Array& arguments_descriptor = |
386 DartEntry::ArgumentsDescriptor(argument_count, argument_names); | 385 DartEntry::ArgumentsDescriptor(argument_count, argument_names); |
387 uword label_address = 0; | 386 uword label_address = 0; |
388 switch (checked_argument_count) { | 387 switch (checked_argument_count) { |
389 case 1: | 388 case 1: |
390 label_address = StubCode::OneArgCheckInlineCacheEntryPoint(); | 389 label_address = StubCode::OneArgCheckInlineCacheEntryPoint(); |
391 break; | 390 break; |
392 case 2: | 391 case 2: |
393 label_address = StubCode::TwoArgsCheckInlineCacheEntryPoint(); | 392 label_address = StubCode::TwoArgsCheckInlineCacheEntryPoint(); |
394 break; | 393 break; |
395 default: | 394 default: |
396 UNIMPLEMENTED(); | 395 UNIMPLEMENTED(); |
397 } | 396 } |
398 ExternalLabel target_label("InlineCache", label_address); | 397 ExternalLabel target_label("InlineCache", label_address); |
399 | 398 |
400 EmitInstanceCall(&target_label, ic_data, arguments_descriptor, argument_count, | 399 EmitInstanceCall(&target_label, ic_data, arguments_descriptor, argument_count, |
401 deopt_id, token_pos, try_index, locs); | 400 deopt_id, token_pos, locs); |
402 } | 401 } |
403 | 402 |
404 | 403 |
405 void FlowGraphCompiler::GenerateStaticCall(intptr_t deopt_id, | 404 void FlowGraphCompiler::GenerateStaticCall(intptr_t deopt_id, |
406 intptr_t token_pos, | 405 intptr_t token_pos, |
407 intptr_t try_index, | |
408 const Function& function, | 406 const Function& function, |
409 intptr_t argument_count, | 407 intptr_t argument_count, |
410 const Array& argument_names, | 408 const Array& argument_names, |
411 LocationSummary* locs) { | 409 LocationSummary* locs) { |
412 const Array& arguments_descriptor = | 410 const Array& arguments_descriptor = |
413 DartEntry::ArgumentsDescriptor(argument_count, argument_names); | 411 DartEntry::ArgumentsDescriptor(argument_count, argument_names); |
414 EmitStaticCall(function, arguments_descriptor, argument_count, | 412 EmitStaticCall(function, arguments_descriptor, argument_count, |
415 deopt_id, token_pos, try_index, locs); | 413 deopt_id, token_pos, locs); |
416 } | 414 } |
417 | 415 |
418 | 416 |
419 void FlowGraphCompiler::GenerateNumberTypeCheck(Register kClassIdReg, | 417 void FlowGraphCompiler::GenerateNumberTypeCheck(Register kClassIdReg, |
420 const AbstractType& type, | 418 const AbstractType& type, |
421 Label* is_instance_lbl, | 419 Label* is_instance_lbl, |
422 Label* is_not_instance_lbl) { | 420 Label* is_not_instance_lbl) { |
423 GrowableArray<intptr_t> args; | 421 GrowableArray<intptr_t> args; |
424 if (type.IsNumberType()) { | 422 if (type.IsNumberType()) { |
425 args.Add(kDoubleCid); | 423 args.Add(kDoubleCid); |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
469 } | 467 } |
470 | 468 |
471 | 469 |
472 void FlowGraphCompiler::EmitTestAndCall(const ICData& ic_data, | 470 void FlowGraphCompiler::EmitTestAndCall(const ICData& ic_data, |
473 Register class_id_reg, | 471 Register class_id_reg, |
474 intptr_t arg_count, | 472 intptr_t arg_count, |
475 const Array& arg_names, | 473 const Array& arg_names, |
476 Label* deopt, | 474 Label* deopt, |
477 intptr_t deopt_id, | 475 intptr_t deopt_id, |
478 intptr_t token_index, | 476 intptr_t token_index, |
479 intptr_t try_index, | |
480 LocationSummary* locs) { | 477 LocationSummary* locs) { |
481 ASSERT(!ic_data.IsNull() && (ic_data.NumberOfChecks() > 0)); | 478 ASSERT(!ic_data.IsNull() && (ic_data.NumberOfChecks() > 0)); |
482 Label match_found; | 479 Label match_found; |
483 for (intptr_t i = 0; i < ic_data.NumberOfChecks(); i++) { | 480 for (intptr_t i = 0; i < ic_data.NumberOfChecks(); i++) { |
484 const bool is_last_check = (i == (ic_data.NumberOfChecks() - 1)); | 481 const bool is_last_check = (i == (ic_data.NumberOfChecks() - 1)); |
485 Label next_test; | 482 Label next_test; |
486 assembler()->cmpl(class_id_reg, Immediate(ic_data.GetReceiverClassIdAt(i))); | 483 assembler()->cmpl(class_id_reg, Immediate(ic_data.GetReceiverClassIdAt(i))); |
487 if (is_last_check) { | 484 if (is_last_check) { |
488 assembler()->j(NOT_EQUAL, deopt); | 485 assembler()->j(NOT_EQUAL, deopt); |
489 } else { | 486 } else { |
490 assembler()->j(NOT_EQUAL, &next_test); | 487 assembler()->j(NOT_EQUAL, &next_test); |
491 } | 488 } |
492 const Function& target = Function::ZoneHandle(ic_data.GetTargetAt(i)); | 489 const Function& target = Function::ZoneHandle(ic_data.GetTargetAt(i)); |
493 GenerateStaticCall(deopt_id, | 490 GenerateStaticCall(deopt_id, |
494 token_index, | 491 token_index, |
495 try_index, | |
496 target, | 492 target, |
497 arg_count, | 493 arg_count, |
498 arg_names, | 494 arg_names, |
499 locs); | 495 locs); |
500 if (!is_last_check) { | 496 if (!is_last_check) { |
501 assembler()->jmp(&match_found); | 497 assembler()->jmp(&match_found); |
502 } | 498 } |
503 assembler()->Bind(&next_test); | 499 assembler()->Bind(&next_test); |
504 } | 500 } |
505 assembler()->Bind(&match_found); | 501 assembler()->Bind(&match_found); |
(...skipping 241 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
747 return; | 743 return; |
748 } | 744 } |
749 } | 745 } |
750 | 746 |
751 // This move is not blocked. | 747 // This move is not blocked. |
752 EmitMove(index); | 748 EmitMove(index); |
753 } | 749 } |
754 | 750 |
755 | 751 |
756 } // namespace dart | 752 } // namespace dart |
OLD | NEW |