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

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

Issue 9623005: Implement branching control flow in the non-optimizing graph 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"
11 #include "vm/code_generator.h" 11 #include "vm/code_generator.h"
12 #include "vm/disassembler.h" 12 #include "vm/disassembler.h"
13 #include "vm/longjump.h" 13 #include "vm/longjump.h"
14 #include "vm/parser.h" 14 #include "vm/parser.h"
15 #include "vm/stub_code.h" 15 #include "vm/stub_code.h"
16 16
17 namespace dart { 17 namespace dart {
18 18
19 DECLARE_FLAG(bool, print_ast); 19 DECLARE_FLAG(bool, print_ast);
20 DECLARE_FLAG(bool, print_scopes); 20 DECLARE_FLAG(bool, print_scopes);
21 DECLARE_FLAG(bool, trace_functions); 21 DECLARE_FLAG(bool, trace_functions);
22 22
23 FlowGraphCompiler::FlowGraphCompiler(
24 Assembler* assembler,
25 const ParsedFunction& parsed_function,
26 const GrowableArray<BlockEntryInstr*>* blocks)
27 : assembler_(assembler),
28 parsed_function_(parsed_function),
29 blocks_(blocks),
30 block_info_(blocks->length()),
31 current_block_(NULL),
32 pc_descriptors_list_(new CodeGenerator::DescriptorList()),
33 stack_local_count_(0) {
34 for (int i = 0; i < blocks->length(); ++i) {
35 block_info_.Add(new BlockInfo());
36 }
37 }
38
39
23 void FlowGraphCompiler::Bailout(const char* reason) { 40 void FlowGraphCompiler::Bailout(const char* reason) {
24 const char* kFormat = "FlowGraphCompiler Bailout: %s %s."; 41 const char* kFormat = "FlowGraphCompiler Bailout: %s %s.";
25 const char* function_name = parsed_function_.function().ToCString(); 42 const char* function_name = parsed_function_.function().ToCString();
26 intptr_t len = OS::SNPrint(NULL, 0, kFormat, function_name, reason) + 1; 43 intptr_t len = OS::SNPrint(NULL, 0, kFormat, function_name, reason) + 1;
27 char* chars = reinterpret_cast<char*>( 44 char* chars = reinterpret_cast<char*>(
28 Isolate::Current()->current_zone()->Allocate(len)); 45 Isolate::Current()->current_zone()->Allocate(len));
29 OS::SNPrint(chars, len, kFormat, function_name, reason); 46 OS::SNPrint(chars, len, kFormat, function_name, reason);
30 const Error& error = Error::Handle( 47 const Error& error = Error::Handle(
31 LanguageError::New(String::Handle(String::New(chars)))); 48 LanguageError::New(String::Handle(String::New(chars))));
32 Isolate::Current()->long_jump_base()->Jump(1, error); 49 Isolate::Current()->long_jump_base()->Jump(1, error);
(...skipping 220 matching lines...) Expand 10 before | Expand all | Expand 10 after
253 __ popq(RBX); // Reciever. 270 __ popq(RBX); // Reciever.
254 __ pushq(RAX); 271 __ pushq(RAX);
255 __ pushq(RBX); 272 __ pushq(RBX);
256 __ pushq(RAX); 273 __ pushq(RAX);
257 EmitInstanceCall(comp->node_id(), comp->token_index(), function_name, 2, 274 EmitInstanceCall(comp->node_id(), comp->token_index(), function_name, 2,
258 Array::ZoneHandle(), 1); 275 Array::ZoneHandle(), 1);
259 __ popq(RAX); 276 __ popq(RAX);
260 } 277 }
261 278
262 279
280 void FlowGraphCompiler::VisitBlocks(
281 const GrowableArray<BlockEntryInstr*>& blocks) {
282 for (intptr_t i = blocks.length() - 1; i >= 0; --i) {
283 // Compile the block entry.
284 current_block_ = blocks[i];
285 Instruction* instr = current_block()->Accept(this);
286 // Compile all successors until an exit, branch, or a block entry.
287 while ((instr != NULL) && !instr->IsBlockEntry()) {
288 instr = instr->Accept(this);
289 }
290
291 if ((instr != NULL) && instr->IsBlockEntry()) {
292 // Block ended with a "goto". We can fall through if it is the
293 // next block in the list. Otherwise, we need a jump.
294 if (i == 0 || (blocks[i - 1] != instr)) {
295 int number = BlockEntryInstr::cast(instr)->block_number();
srdjan 2012/03/07 22:23:06 Discussed in the team and talked with Ivan: Please
Kevin Millikin (Google) 2012/03/08 09:59:53 Removed the static member function from class Bloc
296 __ jmp(&block_info_[number]->label);
297 }
298 }
299 }
300 }
301
302
263 void FlowGraphCompiler::VisitJoinEntry(JoinEntryInstr* instr) { 303 void FlowGraphCompiler::VisitJoinEntry(JoinEntryInstr* instr) {
264 Bailout("JoinEntryInstr"); 304 __ Bind(&block_info_[instr->block_number()]->label);
265 } 305 }
266 306
267 307
268 void FlowGraphCompiler::VisitTargetEntry(TargetEntryInstr* instr) { 308 void FlowGraphCompiler::VisitTargetEntry(TargetEntryInstr* instr) {
269 // Since we don't handle branching control flow yet, there is nothing to do. 309 __ Bind(&block_info_[instr->block_number()]->label);
270 } 310 }
271 311
272 312
273 void FlowGraphCompiler::VisitPickTemp(PickTempInstr* instr) { 313 void FlowGraphCompiler::VisitPickTemp(PickTempInstr* instr) {
274 // Semantics is to copy a stack-allocated temporary to the top of stack. 314 // Semantics is to copy a stack-allocated temporary to the top of stack.
275 // Destination index d is assumed the new top of stack after the 315 // Destination index d is assumed the new top of stack after the
276 // operation, so d-1 is the current top of stack and so d-s-1 is the 316 // operation, so d-1 is the current top of stack and so d-s-1 is the
277 // offset to source index s. 317 // offset to source index s.
278 intptr_t offset = instr->destination() - instr->source() - 1; 318 intptr_t offset = instr->destination() - instr->source() - 1;
279 ASSERT(offset >= 0); 319 ASSERT(offset >= 0);
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
342 __ nop(1); 382 __ nop(1);
343 __ nop(1); 383 __ nop(1);
344 __ nop(1); 384 __ nop(1);
345 AddCurrentDescriptor(PcDescriptors::kReturn, 385 AddCurrentDescriptor(PcDescriptors::kReturn,
346 AstNode::kNoId, 386 AstNode::kNoId,
347 instr->token_index()); 387 instr->token_index());
348 } 388 }
349 389
350 390
351 void FlowGraphCompiler::VisitBranch(BranchInstr* instr) { 391 void FlowGraphCompiler::VisitBranch(BranchInstr* instr) {
352 Bailout("BranchInstr"); 392 // Determine if the true branch is fall through (!negated) or the false
393 // branch is. They cannot both be backwards branches.
394 int index = blocks_->length() - current_block()->block_number() - 1;
srdjan 2012/03/07 22:23:06 intptr_t
Kevin Millikin (Google) 2012/03/08 09:59:53 Done.
395 ASSERT(index != 0);
srdjan 2012/03/07 22:23:06 Maybe safer: (index > 0).
Kevin Millikin (Google) 2012/03/08 09:59:53 Done.
396
397 bool negated = ((*blocks_)[index - 1] == instr->false_successor());
398 ASSERT(!negated == ((*blocks_)[index - 1] == instr->true_successor()));
399
400 LoadValue(instr->value());
401 __ LoadObject(RDX, Bool::ZoneHandle(Bool::True()));
402 __ cmpq(RAX, RDX);
403 if (negated) {
404 __ j(EQUAL, &block_info_[instr->true_successor()->block_number()]->label);
405
srdjan 2012/03/07 22:23:06 Empty line?
Kevin Millikin (Google) 2012/03/08 09:59:53 Deleted.
406 } else {
407 __ j(NOT_EQUAL,
408 &block_info_[instr->false_successor()->block_number()]->label);
409 }
353 } 410 }
354 411
355 412
356 void FlowGraphCompiler::CompileGraph() { 413 void FlowGraphCompiler::CompileGraph() {
357 const Function& function = parsed_function_.function(); 414 const Function& function = parsed_function_.function();
358 if ((function.num_optional_parameters() != 0)) { 415 if ((function.num_optional_parameters() != 0)) {
359 Bailout("function has optional parameters"); 416 Bailout("function has optional parameters");
360 } 417 }
361 LocalScope* scope = parsed_function_.node_sequence()->scope(); 418 LocalScope* scope = parsed_function_.node_sequence()->scope();
362 LocalScope* context_owner = NULL; 419 LocalScope* context_owner = NULL;
363 const int parameter_count = function.num_fixed_parameters(); 420 const int parameter_count = function.num_fixed_parameters();
364 const int first_parameter_index = 1 + parameter_count; 421 const int first_parameter_index = 1 + parameter_count;
365 const int first_local_index = -1; 422 const int first_local_index = -1;
366 int first_free_frame_index = 423 int first_free_frame_index =
367 scope->AllocateVariables(first_parameter_index, 424 scope->AllocateVariables(first_parameter_index,
368 parameter_count, 425 parameter_count,
369 first_local_index, 426 first_local_index,
370 scope, 427 scope,
371 &context_owner); 428 &context_owner);
372 set_stack_local_count(first_local_index - first_free_frame_index); 429 set_stack_local_count(first_local_index - first_free_frame_index);
373 430
374 if (blocks_->length() != 1) Bailout("more than 1 basic block");
375
376 // Specialized version of entry code from CodeGenerator::GenerateEntryCode. 431 // Specialized version of entry code from CodeGenerator::GenerateEntryCode.
377 __ EnterFrame(stack_local_count() * kWordSize); 432 __ EnterFrame(stack_local_count() * kWordSize);
378 #ifdef DEBUG 433 #ifdef DEBUG
379 const bool check_arguments = true; 434 const bool check_arguments = true;
380 #else 435 #else
381 const bool check_arguments = function.IsClosureFunction(); 436 const bool check_arguments = function.IsClosureFunction();
382 #endif 437 #endif
383 if (check_arguments) { 438 if (check_arguments) {
384 // Check that num_fixed <= argc <= num_params. 439 // Check that num_fixed <= argc <= num_params.
385 Label argc_in_range; 440 Label argc_in_range;
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after
488 void FlowGraphCompiler::FinalizeExceptionHandlers(const Code& code) { 543 void FlowGraphCompiler::FinalizeExceptionHandlers(const Code& code) {
489 // We don't compile exception handlers yet. 544 // We don't compile exception handlers yet.
490 code.set_exception_handlers( 545 code.set_exception_handlers(
491 ExceptionHandlers::Handle(ExceptionHandlers::New(0))); 546 ExceptionHandlers::Handle(ExceptionHandlers::New(0)));
492 } 547 }
493 548
494 549
495 } // namespace dart 550 } // namespace dart
496 551
497 #endif // defined TARGET_ARCH_X64 552 #endif // defined TARGET_ARCH_X64
OLDNEW
« runtime/vm/flow_graph_compiler_x64.h ('K') | « runtime/vm/flow_graph_compiler_x64.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698