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 160 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
171 | 171 |
172 | 172 |
173 void FlowGraphCompiler::AddExceptionHandler(intptr_t try_index, | 173 void FlowGraphCompiler::AddExceptionHandler(intptr_t try_index, |
174 intptr_t pc_offset) { | 174 intptr_t pc_offset) { |
175 exception_handlers_list_->AddHandler(try_index, pc_offset); | 175 exception_handlers_list_->AddHandler(try_index, pc_offset); |
176 } | 176 } |
177 | 177 |
178 | 178 |
179 // Uses current pc position and try-index. | 179 // Uses current pc position and try-index. |
180 void FlowGraphCompiler::AddCurrentDescriptor(PcDescriptors::Kind kind, | 180 void FlowGraphCompiler::AddCurrentDescriptor(PcDescriptors::Kind kind, |
181 intptr_t cid, | 181 intptr_t deopt_id, |
182 intptr_t token_pos, | 182 intptr_t token_pos, |
183 intptr_t try_index) { | 183 intptr_t try_index) { |
184 ASSERT((kind != PcDescriptors::kDeopt) || | 184 ASSERT((kind != PcDescriptors::kDeopt) || |
185 frame_register_allocator()->IsSpilled()); | 185 frame_register_allocator()->IsSpilled()); |
186 pc_descriptors_list()->AddDescriptor(kind, | 186 pc_descriptors_list()->AddDescriptor(kind, |
187 assembler()->CodeSize(), | 187 assembler()->CodeSize(), |
188 cid, | 188 deopt_id, |
189 token_pos, | 189 token_pos, |
190 try_index); | 190 try_index); |
191 } | 191 } |
192 | 192 |
193 | 193 |
194 Label* FlowGraphCompiler::AddDeoptStub(intptr_t deopt_id, | 194 Label* FlowGraphCompiler::AddDeoptStub(intptr_t deopt_id, |
195 intptr_t deopt_token_pos, | 195 intptr_t deopt_token_pos, |
196 intptr_t try_index, | 196 intptr_t try_index, |
197 DeoptReasonId reason, | 197 DeoptReasonId reason, |
198 Register reg1, | 198 Register reg1, |
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
292 // Even if an intrinsified version of the function was successfully | 292 // Even if an intrinsified version of the function was successfully |
293 // generated, it may fall through to the non-intrinsified method body. | 293 // generated, it may fall through to the non-intrinsified method body. |
294 if (!FLAG_trace_functions) { | 294 if (!FLAG_trace_functions) { |
295 return Intrinsifier::Intrinsify(parsed_function().function(), assembler()); | 295 return Intrinsifier::Intrinsify(parsed_function().function(), assembler()); |
296 } | 296 } |
297 return false; | 297 return false; |
298 } | 298 } |
299 | 299 |
300 | 300 |
301 void FlowGraphCompiler::GenerateInstanceCall( | 301 void FlowGraphCompiler::GenerateInstanceCall( |
302 intptr_t cid, | 302 intptr_t deopt_id, |
303 intptr_t token_pos, | 303 intptr_t token_pos, |
304 intptr_t try_index, | 304 intptr_t try_index, |
305 const String& function_name, | 305 const String& function_name, |
306 intptr_t argument_count, | 306 intptr_t argument_count, |
307 const Array& argument_names, | 307 const Array& argument_names, |
308 intptr_t checked_argument_count) { | 308 intptr_t checked_argument_count) { |
309 ASSERT(!IsLeaf()); | 309 ASSERT(!IsLeaf()); |
310 ASSERT(frame_register_allocator()->IsSpilled()); | 310 ASSERT(frame_register_allocator()->IsSpilled()); |
311 ICData& ic_data = | 311 ICData& ic_data = |
312 ICData::ZoneHandle(ICData::New(parsed_function().function(), | 312 ICData::ZoneHandle(ICData::New(parsed_function().function(), |
313 function_name, | 313 function_name, |
314 cid, | 314 deopt_id, |
315 checked_argument_count)); | 315 checked_argument_count)); |
316 const Array& arguments_descriptor = | 316 const Array& arguments_descriptor = |
317 DartEntry::ArgumentsDescriptor(argument_count, argument_names); | 317 DartEntry::ArgumentsDescriptor(argument_count, argument_names); |
318 uword label_address = 0; | 318 uword label_address = 0; |
319 switch (checked_argument_count) { | 319 switch (checked_argument_count) { |
320 case 1: | 320 case 1: |
321 label_address = StubCode::OneArgCheckInlineCacheEntryPoint(); | 321 label_address = StubCode::OneArgCheckInlineCacheEntryPoint(); |
322 break; | 322 break; |
323 case 2: | 323 case 2: |
324 label_address = StubCode::TwoArgsCheckInlineCacheEntryPoint(); | 324 label_address = StubCode::TwoArgsCheckInlineCacheEntryPoint(); |
325 break; | 325 break; |
326 default: | 326 default: |
327 UNIMPLEMENTED(); | 327 UNIMPLEMENTED(); |
328 } | 328 } |
329 ExternalLabel target_label("InlineCache", label_address); | 329 ExternalLabel target_label("InlineCache", label_address); |
330 | 330 |
331 const intptr_t descr_offset = EmitInstanceCall(&target_label, | 331 const intptr_t descr_offset = EmitInstanceCall(&target_label, |
332 ic_data, | 332 ic_data, |
333 arguments_descriptor, | 333 arguments_descriptor, |
334 argument_count); | 334 argument_count); |
335 pc_descriptors_list()->AddDescriptor(PcDescriptors::kIcCall, | 335 pc_descriptors_list()->AddDescriptor(PcDescriptors::kIcCall, |
336 descr_offset, | 336 descr_offset, |
337 cid, | 337 deopt_id, |
338 token_pos, | 338 token_pos, |
339 try_index); | 339 try_index); |
340 } | 340 } |
341 | 341 |
342 | 342 |
343 void FlowGraphCompiler::GenerateStaticCall(intptr_t cid, | 343 void FlowGraphCompiler::GenerateStaticCall(intptr_t deopt_id, |
344 intptr_t token_pos, | 344 intptr_t token_pos, |
345 intptr_t try_index, | 345 intptr_t try_index, |
346 const Function& function, | 346 const Function& function, |
347 intptr_t argument_count, | 347 intptr_t argument_count, |
348 const Array& argument_names) { | 348 const Array& argument_names) { |
349 ASSERT(frame_register_allocator()->IsSpilled()); | 349 ASSERT(frame_register_allocator()->IsSpilled()); |
350 | 350 |
351 const Array& arguments_descriptor = | 351 const Array& arguments_descriptor = |
352 DartEntry::ArgumentsDescriptor(argument_count, argument_names); | 352 DartEntry::ArgumentsDescriptor(argument_count, argument_names); |
353 const intptr_t descr_offset = EmitStaticCall(function, | 353 const intptr_t descr_offset = EmitStaticCall(function, |
354 arguments_descriptor, | 354 arguments_descriptor, |
355 argument_count); | 355 argument_count); |
356 pc_descriptors_list()->AddDescriptor(PcDescriptors::kFuncCall, | 356 pc_descriptors_list()->AddDescriptor(PcDescriptors::kFuncCall, |
357 descr_offset, | 357 descr_offset, |
358 cid, | 358 deopt_id, |
359 token_pos, | 359 token_pos, |
360 try_index); | 360 try_index); |
361 } | 361 } |
362 | 362 |
363 | 363 |
364 void FlowGraphCompiler::GenerateNumberTypeCheck(Register kClassIdReg, | 364 void FlowGraphCompiler::GenerateNumberTypeCheck(Register kClassIdReg, |
365 const AbstractType& type, | 365 const AbstractType& type, |
366 Label* is_instance_lbl, | 366 Label* is_instance_lbl, |
367 Label* is_not_instance_lbl) { | 367 Label* is_not_instance_lbl) { |
368 GrowableArray<intptr_t> args; | 368 GrowableArray<intptr_t> args; |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
412 instr->PrintTo(&f); | 412 instr->PrintTo(&f); |
413 assembler()->Comment("%s", buffer); | 413 assembler()->Comment("%s", buffer); |
414 } | 414 } |
415 | 415 |
416 | 416 |
417 void FlowGraphCompiler::EmitLoadIndexedGeneric(LoadIndexedComp* comp) { | 417 void FlowGraphCompiler::EmitLoadIndexedGeneric(LoadIndexedComp* comp) { |
418 const String& function_name = | 418 const String& function_name = |
419 String::ZoneHandle(Symbols::New(Token::Str(Token::kINDEX))); | 419 String::ZoneHandle(Symbols::New(Token::Str(Token::kINDEX))); |
420 | 420 |
421 AddCurrentDescriptor(PcDescriptors::kDeopt, | 421 AddCurrentDescriptor(PcDescriptors::kDeopt, |
422 comp->cid(), | 422 comp->deopt_id(), |
423 comp->token_pos(), | 423 comp->token_pos(), |
424 comp->try_index()); | 424 comp->try_index()); |
425 | 425 |
426 const intptr_t kNumArguments = 2; | 426 const intptr_t kNumArguments = 2; |
427 const intptr_t kNumArgsChecked = 1; // Type-feedback. | 427 const intptr_t kNumArgsChecked = 1; // Type-feedback. |
428 GenerateInstanceCall(comp->cid(), | 428 GenerateInstanceCall(comp->deopt_id(), |
429 comp->token_pos(), | 429 comp->token_pos(), |
430 comp->try_index(), | 430 comp->try_index(), |
431 function_name, | 431 function_name, |
432 kNumArguments, | 432 kNumArguments, |
433 Array::ZoneHandle(), // No optional arguments. | 433 Array::ZoneHandle(), // No optional arguments. |
434 kNumArgsChecked); | 434 kNumArgsChecked); |
435 } | 435 } |
436 | 436 |
437 | 437 |
438 void FlowGraphCompiler::EmitTestAndCall(const ICData& ic_data, | 438 void FlowGraphCompiler::EmitTestAndCall(const ICData& ic_data, |
439 Register class_id_reg, | 439 Register class_id_reg, |
440 intptr_t arg_count, | 440 intptr_t arg_count, |
441 const Array& arg_names, | 441 const Array& arg_names, |
442 Label* deopt, | 442 Label* deopt, |
443 Label* done, | 443 Label* done, |
444 intptr_t cid, | 444 intptr_t deopt_id, |
445 intptr_t token_index, | 445 intptr_t token_index, |
446 intptr_t try_index) { | 446 intptr_t try_index) { |
447 ASSERT(!ic_data.IsNull() && (ic_data.NumberOfChecks() > 0)); | 447 ASSERT(!ic_data.IsNull() && (ic_data.NumberOfChecks() > 0)); |
448 Label match_found; | 448 Label match_found; |
449 for (intptr_t i = 0; i < ic_data.NumberOfChecks(); i++) { | 449 for (intptr_t i = 0; i < ic_data.NumberOfChecks(); i++) { |
450 const bool is_last_check = (i == (ic_data.NumberOfChecks() - 1)); | 450 const bool is_last_check = (i == (ic_data.NumberOfChecks() - 1)); |
451 Label next_test; | 451 Label next_test; |
452 assembler()->cmpl(class_id_reg, Immediate(ic_data.GetReceiverClassIdAt(i))); | 452 assembler()->cmpl(class_id_reg, Immediate(ic_data.GetReceiverClassIdAt(i))); |
453 if (is_last_check) { | 453 if (is_last_check) { |
454 assembler()->j(NOT_EQUAL, deopt); | 454 assembler()->j(NOT_EQUAL, deopt); |
455 } else { | 455 } else { |
456 assembler()->j(NOT_EQUAL, &next_test); | 456 assembler()->j(NOT_EQUAL, &next_test); |
457 } | 457 } |
458 const Function& target = Function::ZoneHandle(ic_data.GetTargetAt(i)); | 458 const Function& target = Function::ZoneHandle(ic_data.GetTargetAt(i)); |
459 GenerateStaticCall(cid, | 459 GenerateStaticCall(deopt_id, |
460 token_index, | 460 token_index, |
461 try_index, | 461 try_index, |
462 target, | 462 target, |
463 arg_count, | 463 arg_count, |
464 arg_names); | 464 arg_names); |
465 if (!is_last_check) { | 465 if (!is_last_check) { |
466 assembler()->jmp(&match_found); | 466 assembler()->jmp(&match_found); |
467 } | 467 } |
468 assembler()->Bind(&next_test); | 468 assembler()->Bind(&next_test); |
469 } | 469 } |
(...skipping 331 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
801 return; | 801 return; |
802 } | 802 } |
803 } | 803 } |
804 | 804 |
805 // This move is not blocked. | 805 // This move is not blocked. |
806 EmitMove(index); | 806 EmitMove(index); |
807 } | 807 } |
808 | 808 |
809 | 809 |
810 } // namespace dart | 810 } // namespace dart |
OLD | NEW |