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

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

Issue 9664062: Support allocating and calling closures in the new non-optimizing compiler. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 8 years, 9 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_X64. 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_X64.
6 #if defined(TARGET_ARCH_X64) 6 #if defined(TARGET_ARCH_X64)
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 22
23 FlowGraphCompiler::FlowGraphCompiler( 23 FlowGraphCompiler::FlowGraphCompiler(
24 Assembler* assembler, 24 Assembler* assembler,
25 const ParsedFunction& parsed_function, 25 const ParsedFunction& parsed_function,
26 const GrowableArray<BlockEntryInstr*>* blocks) 26 const GrowableArray<BlockEntryInstr*>* blocks)
27 : assembler_(assembler), 27 : assembler_(assembler),
28 parsed_function_(parsed_function), 28 parsed_function_(parsed_function),
29 blocks_(blocks), 29 blocks_(blocks),
30 block_info_(blocks->length()), 30 block_info_(blocks->length()),
31 current_block_(NULL), 31 current_block_(NULL),
32 pc_descriptors_list_(new CodeGenerator::DescriptorList()), 32 pc_descriptors_list_(new CodeGenerator::DescriptorList()) {
33 stack_local_count_(0) {
34 for (int i = 0; i < blocks->length(); ++i) { 33 for (int i = 0; i < blocks->length(); ++i) {
35 block_info_.Add(new BlockInfo()); 34 block_info_.Add(new BlockInfo());
36 } 35 }
37 } 36 }
38 37
39 38
40 FlowGraphCompiler::~FlowGraphCompiler() { 39 FlowGraphCompiler::~FlowGraphCompiler() {
41 // BlockInfos are zone-allocated, so their destructors are not called. 40 // BlockInfos are zone-allocated, so their destructors are not called.
42 // Verify the labels explicitly here. 41 // Verify the labels explicitly here.
43 for (int i = 0; i < block_info_.length(); ++i) { 42 for (int i = 0; i < block_info_.length(); ++i) {
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after
157 default: 156 default:
158 UNIMPLEMENTED(); 157 UNIMPLEMENTED();
159 } 158 }
160 ExternalLabel target_label("InlineCache", label_address); 159 ExternalLabel target_label("InlineCache", label_address);
161 __ call(&target_label); 160 __ call(&target_label);
162 AddCurrentDescriptor(PcDescriptors::kIcCall, node_id, token_index); 161 AddCurrentDescriptor(PcDescriptors::kIcCall, node_id, token_index);
163 __ addq(RSP, Immediate(argument_count * kWordSize)); 162 __ addq(RSP, Immediate(argument_count * kWordSize));
164 } 163 }
165 164
166 165
166 void FlowGraphCompiler::VisitCurrentContext(CurrentContextComp* comp) {
167 __ movq(RAX, CTX);
168 }
169
170
171 void FlowGraphCompiler::VisitClosureCall(ClosureCallComp* comp) {
172 ASSERT(comp->context()->IsTemp());
173 ASSERT(VerifyCallComputation(comp));
174 // The arguments to the stub include the closure. The arguments
175 // descriptor describes the closure's arguments (and so does not include
176 // the closure).
177 int argument_count = comp->ArgumentCount();
178 const Array& arguments_descriptor =
179 CodeGenerator::ArgumentsDescriptor(argument_count - 1,
180 comp->argument_names());
181 __ LoadObject(R10, arguments_descriptor);
182
183 GenerateCall(comp->token_index(),
184 &StubCode::CallClosureFunctionLabel(),
185 PcDescriptors::kOther);
186 __ addq(RSP, Immediate(argument_count * kWordSize));
187 __ popq(CTX);
188 }
189
190
167 void FlowGraphCompiler::VisitInstanceCall(InstanceCallComp* comp) { 191 void FlowGraphCompiler::VisitInstanceCall(InstanceCallComp* comp) {
168 ASSERT(VerifyCallComputation(comp)); 192 ASSERT(VerifyCallComputation(comp));
169 EmitInstanceCall(comp->node_id(), 193 EmitInstanceCall(comp->node_id(),
170 comp->token_index(), 194 comp->token_index(),
171 comp->function_name(), 195 comp->function_name(),
172 comp->ArgumentCount(), 196 comp->ArgumentCount(),
173 comp->argument_names(), 197 comp->argument_names(),
174 comp->checked_argument_count()); 198 comp->checked_argument_count());
175 } 199 }
176 200
(...skipping 182 matching lines...) Expand 10 before | Expand all | Expand 10 after
359 if (comp->ElementAt(i)->IsTemp()) { 383 if (comp->ElementAt(i)->IsTemp()) {
360 __ popq(Address(RCX, i * kWordSize)); 384 __ popq(Address(RCX, i * kWordSize));
361 } else { 385 } else {
362 LoadValue(RDX, comp->ElementAt(i)); 386 LoadValue(RDX, comp->ElementAt(i));
363 __ movq(Address(RCX, i * kWordSize), RDX); 387 __ movq(Address(RCX, i * kWordSize), RDX);
364 } 388 }
365 } 389 }
366 } 390 }
367 391
368 392
393 void FlowGraphCompiler::VisitCreateClosure(CreateClosureComp* comp) {
394 const Function& function = comp->function();
395 const Code& stub = Code::Handle(
396 StubCode::GetAllocationStubForClosure(function));
397 const ExternalLabel label(function.ToCString(), stub.EntryPoint());
398 GenerateCall(comp->token_index(), &label, PcDescriptors::kOther);
399
400 const Class& cls = Class::Handle(function.signature_class());
401 if (cls.HasTypeArguments()) {
402 __ popq(RCX); // Discard type arguments.
403 }
404 if (function.IsImplicitInstanceClosureFunction()) {
405 __ popq(RCX); // Discard receiver.
406 }
407 }
408
409
369 void FlowGraphCompiler::VisitBlocks( 410 void FlowGraphCompiler::VisitBlocks(
370 const GrowableArray<BlockEntryInstr*>& blocks) { 411 const GrowableArray<BlockEntryInstr*>& blocks) {
371 for (intptr_t i = blocks.length() - 1; i >= 0; --i) { 412 for (intptr_t i = blocks.length() - 1; i >= 0; --i) {
372 // Compile the block entry. 413 // Compile the block entry.
373 current_block_ = blocks[i]; 414 current_block_ = blocks[i];
374 Instruction* instr = current_block()->Accept(this); 415 Instruction* instr = current_block()->Accept(this);
375 // Compile all successors until an exit, branch, or a block entry. 416 // Compile all successors until an exit, branch, or a block entry.
376 while ((instr != NULL) && !instr->IsBlockEntry()) { 417 while ((instr != NULL) && !instr->IsBlockEntry()) {
377 instr = instr->Accept(this); 418 instr = instr->Accept(this);
378 } 419 }
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
433 } 474 }
434 475
435 476
436 void FlowGraphCompiler::VisitReturn(ReturnInstr* instr) { 477 void FlowGraphCompiler::VisitReturn(ReturnInstr* instr) {
437 LoadValue(RAX, instr->value()); 478 LoadValue(RAX, instr->value());
438 479
439 #ifdef DEBUG 480 #ifdef DEBUG
440 // Check that the entry stack size matches the exit stack size. 481 // Check that the entry stack size matches the exit stack size.
441 __ movq(R10, RBP); 482 __ movq(R10, RBP);
442 __ subq(R10, RSP); 483 __ subq(R10, RSP);
443 __ cmpq(R10, Immediate(stack_local_count() * kWordSize)); 484 __ cmpq(R10, Immediate(parsed_function_.local_count() * kWordSize));
444 Label stack_ok; 485 Label stack_ok;
445 __ j(EQUAL, &stack_ok, Assembler::kNearJump); 486 __ j(EQUAL, &stack_ok, Assembler::kNearJump);
446 __ Stop("Exit stack size does not match the entry stack size."); 487 __ Stop("Exit stack size does not match the entry stack size.");
447 __ Bind(&stack_ok); 488 __ Bind(&stack_ok);
448 #endif // DEBUG. 489 #endif // DEBUG.
449 490
450 if (FLAG_trace_functions) { 491 if (FLAG_trace_functions) {
451 __ pushq(RAX); // Preserve result. 492 __ pushq(RAX); // Preserve result.
452 const Function& function = 493 const Function& function =
453 Function::ZoneHandle(parsed_function_.function().raw()); 494 Function::ZoneHandle(parsed_function_.function().raw());
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
493 if (negated) { 534 if (negated) {
494 __ j(EQUAL, &block_info_[instr->true_successor()->block_number()]->label); 535 __ j(EQUAL, &block_info_[instr->true_successor()->block_number()]->label);
495 } else { 536 } else {
496 __ j(NOT_EQUAL, 537 __ j(NOT_EQUAL,
497 &block_info_[instr->false_successor()->block_number()]->label); 538 &block_info_[instr->false_successor()->block_number()]->label);
498 } 539 }
499 } 540 }
500 541
501 542
502 void FlowGraphCompiler::CompileGraph() { 543 void FlowGraphCompiler::CompileGraph() {
544 // Specialized version of entry code from CodeGenerator::GenerateEntryCode.
503 const Function& function = parsed_function_.function(); 545 const Function& function = parsed_function_.function();
504 if ((function.num_optional_parameters() != 0)) { 546
505 Bailout("function has optional parameters"); 547 // We don't implement copied parameters yet and should have bailed out
506 } 548 // from the graph builder.
507 LocalScope* scope = parsed_function_.node_sequence()->scope(); 549 ASSERT(function.num_optional_parameters() == 0);
508 LocalScope* context_owner = NULL;
509 const int parameter_count = function.num_fixed_parameters(); 550 const int parameter_count = function.num_fixed_parameters();
510 const int first_parameter_index = 1 + parameter_count; 551 const int local_count = parsed_function_.local_count();
511 const int first_local_index = -1; 552 __ EnterFrame(local_count * kWordSize);
512 int first_free_frame_index =
513 scope->AllocateVariables(first_parameter_index,
514 parameter_count,
515 first_local_index,
516 scope,
517 &context_owner);
518 set_stack_local_count(first_local_index - first_free_frame_index);
519
520 // Specialized version of entry code from CodeGenerator::GenerateEntryCode.
521 __ EnterFrame(stack_local_count() * kWordSize);
522 #ifdef DEBUG 553 #ifdef DEBUG
523 const bool check_arguments = true; 554 const bool check_arguments = true;
524 #else 555 #else
525 const bool check_arguments = function.IsClosureFunction(); 556 const bool check_arguments = function.IsClosureFunction();
526 #endif 557 #endif
527 if (check_arguments) { 558 if (check_arguments) {
528 // Check that num_fixed <= argc <= num_params. 559 // Check that num_fixed <= argc <= num_params.
529 Label argc_in_range; 560 Label argc_in_range;
530 // Total number of args is the first Smi in args descriptor array (R10). 561 // Total number of args is the first Smi in args descriptor array (R10).
531 __ movq(RAX, FieldAddress(R10, Array::data_offset())); 562 __ movq(RAX, FieldAddress(R10, Array::data_offset()));
532 __ cmpq(RAX, Immediate(Smi::RawValue(parameter_count))); 563 __ cmpq(RAX, Immediate(Smi::RawValue(parameter_count)));
533 __ j(EQUAL, &argc_in_range, Assembler::kNearJump); 564 __ j(EQUAL, &argc_in_range, Assembler::kNearJump);
534 if (function.IsClosureFunction()) { 565 if (function.IsClosureFunction()) {
535 GenerateCallRuntime(AstNode::kNoId, 566 GenerateCallRuntime(AstNode::kNoId,
536 function.token_index(), 567 function.token_index(),
537 kClosureArgumentMismatchRuntimeEntry); 568 kClosureArgumentMismatchRuntimeEntry);
538 } else { 569 } else {
539 __ Stop("Wrong number of arguments"); 570 __ Stop("Wrong number of arguments");
540 } 571 }
541 __ Bind(&argc_in_range); 572 __ Bind(&argc_in_range);
542 } 573 }
543 574
544 // Initialize locals to null. 575 // Initialize locals to null.
545 if (stack_local_count() > 0) { 576 if (local_count > 0) {
546 __ movq(RAX, Immediate(reinterpret_cast<intptr_t>(Object::null()))); 577 __ movq(RAX, Immediate(reinterpret_cast<intptr_t>(Object::null())));
547 for (int i = 0; i < stack_local_count(); ++i) { 578 const int base = parsed_function_.first_local_index();
579 for (int i = 0; i < local_count; ++i) {
548 // Subtract index i (locals lie at lower addresses than RBP). 580 // Subtract index i (locals lie at lower addresses than RBP).
549 __ movq(Address(RBP, (first_local_index - i) * kWordSize), RAX); 581 __ movq(Address(RBP, (base - i) * kWordSize), RAX);
550 } 582 }
551 } 583 }
552 584
553 // Generate stack overflow check. 585 // Generate stack overflow check.
554 __ movq(TMP, Immediate(Isolate::Current()->stack_limit_address())); 586 __ movq(TMP, Immediate(Isolate::Current()->stack_limit_address()));
555 __ cmpq(RSP, Address(TMP, 0)); 587 __ cmpq(RSP, Address(TMP, 0));
556 Label no_stack_overflow; 588 Label no_stack_overflow;
557 __ j(ABOVE, &no_stack_overflow, Assembler::kNearJump); 589 __ j(ABOVE, &no_stack_overflow, Assembler::kNearJump);
558 GenerateCallRuntime(AstNode::kNoId, 590 GenerateCallRuntime(AstNode::kNoId,
559 function.token_index(), 591 function.token_index(),
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
632 void FlowGraphCompiler::FinalizeExceptionHandlers(const Code& code) { 664 void FlowGraphCompiler::FinalizeExceptionHandlers(const Code& code) {
633 // We don't compile exception handlers yet. 665 // We don't compile exception handlers yet.
634 code.set_exception_handlers( 666 code.set_exception_handlers(
635 ExceptionHandlers::Handle(ExceptionHandlers::New(0))); 667 ExceptionHandlers::Handle(ExceptionHandlers::New(0)));
636 } 668 }
637 669
638 670
639 } // namespace dart 671 } // namespace dart
640 672
641 #endif // defined TARGET_ARCH_X64 673 #endif // defined TARGET_ARCH_X64
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698