| 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 |