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

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

Issue 10035006: Share intrinsification framework across architectures, started on instrinsification in the new comp… (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 years, 8 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 "lib/error.h" 10 #include "lib/error.h"
11 #include "vm/ast_printer.h" 11 #include "vm/ast_printer.h"
12 #include "vm/code_descriptors.h" 12 #include "vm/code_descriptors.h"
13 #include "vm/code_generator.h" 13 #include "vm/code_generator.h"
14 #include "vm/debugger.h"
14 #include "vm/disassembler.h" 15 #include "vm/disassembler.h"
16 #include "vm/intrinsifier.h"
15 #include "vm/longjump.h" 17 #include "vm/longjump.h"
16 #include "vm/object_store.h" 18 #include "vm/object_store.h"
17 #include "vm/parser.h" 19 #include "vm/parser.h"
18 #include "vm/stub_code.h" 20 #include "vm/stub_code.h"
19 21
20 namespace dart { 22 namespace dart {
21 23
22 DECLARE_FLAG(bool, enable_type_checks); 24 DECLARE_FLAG(bool, enable_type_checks);
25 DECLARE_FLAG(bool, intrinsify);
26 DECLARE_FLAG(bool, optimization_counter_threshold);
23 DECLARE_FLAG(bool, print_ast); 27 DECLARE_FLAG(bool, print_ast);
24 DECLARE_FLAG(bool, print_scopes); 28 DECLARE_FLAG(bool, print_scopes);
29 DECLARE_FLAG(bool, report_usage_count);
25 DECLARE_FLAG(bool, trace_functions); 30 DECLARE_FLAG(bool, trace_functions);
26 31
32
27 FlowGraphCompiler::FlowGraphCompiler( 33 FlowGraphCompiler::FlowGraphCompiler(
28 Assembler* assembler, 34 Assembler* assembler,
29 const ParsedFunction& parsed_function, 35 const ParsedFunction& parsed_function,
30 const GrowableArray<BlockEntryInstr*>& block_order) 36 const GrowableArray<BlockEntryInstr*>& block_order)
31 : FlowGraphVisitor(block_order), 37 : FlowGraphVisitor(block_order),
32 assembler_(assembler), 38 assembler_(assembler),
33 parsed_function_(parsed_function), 39 parsed_function_(parsed_function),
34 block_info_(block_order.length()), 40 block_info_(block_order.length()),
35 current_block_(NULL), 41 current_block_(NULL),
36 pc_descriptors_list_(new DescriptorList()), 42 pc_descriptors_list_(new DescriptorList()),
(...skipping 1476 matching lines...) Expand 10 before | Expand all | Expand 10 after
1513 __ jmp(&null_args_loop_condition, Assembler::kNearJump); 1519 __ jmp(&null_args_loop_condition, Assembler::kNearJump);
1514 const Address original_argument_addr(RBP, RCX, TIMES_8, 2 * kWordSize); 1520 const Address original_argument_addr(RBP, RCX, TIMES_8, 2 * kWordSize);
1515 __ Bind(&null_args_loop); 1521 __ Bind(&null_args_loop);
1516 __ movq(original_argument_addr, raw_null); 1522 __ movq(original_argument_addr, raw_null);
1517 __ Bind(&null_args_loop_condition); 1523 __ Bind(&null_args_loop_condition);
1518 __ decq(RCX); 1524 __ decq(RCX);
1519 __ j(POSITIVE, &null_args_loop, Assembler::kNearJump); 1525 __ j(POSITIVE, &null_args_loop, Assembler::kNearJump);
1520 } 1526 }
1521 1527
1522 1528
1529 bool FlowGraphCompiler::CanOptimize() {
1530 return
1531 !FLAG_report_usage_count &&
1532 (FLAG_optimization_counter_threshold >= 0) &&
1533 !Isolate::Current()->debugger()->IsActive();
1534 }
1535
1536
1537 void FlowGraphCompiler::IntrinsifyGetter() {
1538 // TOS: return address.
1539 // +1 : receiver.
1540 // Sequence node has one return node, its input is oad field node.
regis 2012/04/17 21:15:31 oad?
srdjan 2012/04/17 21:37:54 toad? road? aaaah .. load!
1541 const SequenceNode& sequence_node = *parsed_function_.node_sequence();
1542 ASSERT(sequence_node.length() == 1);
1543 ASSERT(sequence_node.NodeAt(0)->IsReturnNode());
1544 const ReturnNode& return_node = *sequence_node.NodeAt(0)->AsReturnNode();
1545 ASSERT(return_node.value()->IsLoadInstanceFieldNode());
1546 const LoadInstanceFieldNode& load_node =
1547 *return_node.value()->AsLoadInstanceFieldNode();
1548 __ movq(RAX, Address(RSP, 1 * kWordSize));
1549 __ movq(RAX, FieldAddress(RAX, load_node.field().Offset()));
1550 __ ret();
1551 }
1552
1553
1554 void FlowGraphCompiler::IntrinsifySetter() {
1555 // TOS: return address.
1556 // +1 : value
1557 // +2 : receiver.
1558 // Sequence node has one store node and one return NULL node.
1559 const SequenceNode& sequence_node = *parsed_function_.node_sequence();
1560 ASSERT(sequence_node.length() == 2);
1561 ASSERT(sequence_node.NodeAt(0)->IsStoreInstanceFieldNode());
1562 ASSERT(sequence_node.NodeAt(1)->IsReturnNode());
1563 const StoreInstanceFieldNode& store_node =
1564 *sequence_node.NodeAt(0)->AsStoreInstanceFieldNode();
1565 __ movq(RAX, Address(RSP, 2 * kWordSize)); // Receiver.
1566 __ movq(RBX, Address(RSP, 1 * kWordSize)); // Value.
1567 __ StoreIntoObject(RAX, FieldAddress(RAX, store_node.field().Offset()), RBX);
1568 const Immediate raw_null =
1569 Immediate(reinterpret_cast<intptr_t>(Object::null()));
1570 __ movq(RAX, raw_null);
1571 __ ret();
1572 }
1573
1574
1575 // Returns 'true' if code generation for this function is complete, i.e.,
1576 // no fall-through to regular code is needed.
1577 bool FlowGraphCompiler::TryIntrinsify() {
1578 if (!CanOptimize()) return false;
1579 // Intrinsification skips arguments checks, therefore disable if in checked
1580 // mode.
1581 if (FLAG_intrinsify && !FLAG_trace_functions && !FLAG_enable_type_checks) {
1582 if ((parsed_function_.function().kind() == RawFunction::kImplicitGetter)) {
1583 IntrinsifyGetter();
1584 return true;
1585 }
1586 if ((parsed_function_.function().kind() == RawFunction::kImplicitSetter)) {
1587 IntrinsifySetter();
1588 return true;
1589 }
1590 }
1591 // Even if an intrinsified version of the function was successfully
1592 // generated, it may fall through to the non-intrinsified method body.
1593 if (!FLAG_trace_functions) {
1594 return Intrinsifier::Intrinsify(parsed_function_.function(), assembler_);
1595 }
1596 return false;
1597 }
1598
1599
1523 // TODO(srdjan): Investigate where to put the argument type checks for 1600 // TODO(srdjan): Investigate where to put the argument type checks for
1524 // checked mode. 1601 // checked mode.
1525 void FlowGraphCompiler::CompileGraph() { 1602 void FlowGraphCompiler::CompileGraph() {
1603 if (TryIntrinsify()) {
1604 // Make it patchable.
1605 __ nop(2);
regis 2012/04/17 21:15:31 Why 2?
srdjan 2012/04/17 21:37:54 Patcheable entry needs certain code size. nop(2)
1606 __ int3();
1607 __ jmp(&StubCode::FixCallersTargetLabel());
1608 return;
1609 }
1526 // Specialized version of entry code from CodeGenerator::GenerateEntryCode. 1610 // Specialized version of entry code from CodeGenerator::GenerateEntryCode.
1527 const Function& function = parsed_function_.function(); 1611 const Function& function = parsed_function_.function();
1528 1612
1529 const int parameter_count = function.num_fixed_parameters(); 1613 const int parameter_count = function.num_fixed_parameters();
1530 const int num_copied_params = parsed_function_.copied_parameter_count(); 1614 const int num_copied_params = parsed_function_.copied_parameter_count();
1531 const int local_count = parsed_function_.stack_local_count(); 1615 const int local_count = parsed_function_.stack_local_count();
1532 __ EnterFrame(StackSize() * kWordSize); 1616 __ EnterFrame(StackSize() * kWordSize);
1533 1617
1534 // We check the number of passed arguments when we have to copy them due to 1618 // We check the number of passed arguments when we have to copy them due to
1535 // the presence of optional named parameters. 1619 // the presence of optional named parameters.
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after
1659 ASSERT(exception_handlers_list_ != NULL); 1743 ASSERT(exception_handlers_list_ != NULL);
1660 const ExceptionHandlers& handlers = ExceptionHandlers::Handle( 1744 const ExceptionHandlers& handlers = ExceptionHandlers::Handle(
1661 exception_handlers_list_->FinalizeExceptionHandlers(code.EntryPoint())); 1745 exception_handlers_list_->FinalizeExceptionHandlers(code.EntryPoint()));
1662 code.set_exception_handlers(handlers); 1746 code.set_exception_handlers(handlers);
1663 } 1747 }
1664 1748
1665 1749
1666 } // namespace dart 1750 } // namespace dart
1667 1751
1668 #endif // defined TARGET_ARCH_X64 1752 #endif // defined TARGET_ARCH_X64
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698