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

Unified 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « runtime/vm/flow_graph_compiler_x64.h ('k') | runtime/vm/intrinsifier.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: runtime/vm/flow_graph_compiler_x64.cc
===================================================================
--- runtime/vm/flow_graph_compiler_x64.cc (revision 6659)
+++ runtime/vm/flow_graph_compiler_x64.cc (working copy)
@@ -11,7 +11,9 @@
#include "vm/ast_printer.h"
#include "vm/code_descriptors.h"
#include "vm/code_generator.h"
+#include "vm/debugger.h"
#include "vm/disassembler.h"
+#include "vm/intrinsifier.h"
#include "vm/longjump.h"
#include "vm/object_store.h"
#include "vm/parser.h"
@@ -20,10 +22,14 @@
namespace dart {
DECLARE_FLAG(bool, enable_type_checks);
+DECLARE_FLAG(bool, intrinsify);
+DECLARE_FLAG(bool, optimization_counter_threshold);
DECLARE_FLAG(bool, print_ast);
DECLARE_FLAG(bool, print_scopes);
+DECLARE_FLAG(bool, report_usage_count);
DECLARE_FLAG(bool, trace_functions);
+
FlowGraphCompiler::FlowGraphCompiler(
Assembler* assembler,
const ParsedFunction& parsed_function,
@@ -1519,9 +1525,88 @@
}
+bool FlowGraphCompiler::CanOptimize() {
+ return
+ !FLAG_report_usage_count &&
+ (FLAG_optimization_counter_threshold >= 0) &&
+ !Isolate::Current()->debugger()->IsActive();
+}
+
+
+void FlowGraphCompiler::IntrinsifyGetter() {
+ // TOS: return address.
+ // +1 : receiver.
+ // Sequence node has one return node, its input is load field node.
+ const SequenceNode& sequence_node = *parsed_function_.node_sequence();
+ ASSERT(sequence_node.length() == 1);
+ ASSERT(sequence_node.NodeAt(0)->IsReturnNode());
+ const ReturnNode& return_node = *sequence_node.NodeAt(0)->AsReturnNode();
+ ASSERT(return_node.value()->IsLoadInstanceFieldNode());
+ const LoadInstanceFieldNode& load_node =
+ *return_node.value()->AsLoadInstanceFieldNode();
+ __ movq(RAX, Address(RSP, 1 * kWordSize));
+ __ movq(RAX, FieldAddress(RAX, load_node.field().Offset()));
+ __ ret();
+}
+
+
+void FlowGraphCompiler::IntrinsifySetter() {
+ // TOS: return address.
+ // +1 : value
+ // +2 : receiver.
+ // Sequence node has one store node and one return NULL node.
+ const SequenceNode& sequence_node = *parsed_function_.node_sequence();
+ ASSERT(sequence_node.length() == 2);
+ ASSERT(sequence_node.NodeAt(0)->IsStoreInstanceFieldNode());
+ ASSERT(sequence_node.NodeAt(1)->IsReturnNode());
+ const StoreInstanceFieldNode& store_node =
+ *sequence_node.NodeAt(0)->AsStoreInstanceFieldNode();
+ __ movq(RAX, Address(RSP, 2 * kWordSize)); // Receiver.
+ __ movq(RBX, Address(RSP, 1 * kWordSize)); // Value.
+ __ StoreIntoObject(RAX, FieldAddress(RAX, store_node.field().Offset()), RBX);
+ const Immediate raw_null =
+ Immediate(reinterpret_cast<intptr_t>(Object::null()));
+ __ movq(RAX, raw_null);
+ __ ret();
+}
+
+
+// Returns 'true' if code generation for this function is complete, i.e.,
+// no fall-through to regular code is needed.
+bool FlowGraphCompiler::TryIntrinsify() {
+ if (!CanOptimize()) return false;
+ // Intrinsification skips arguments checks, therefore disable if in checked
+ // mode.
+ if (FLAG_intrinsify && !FLAG_trace_functions && !FLAG_enable_type_checks) {
+ if ((parsed_function_.function().kind() == RawFunction::kImplicitGetter)) {
+ IntrinsifyGetter();
+ return true;
+ }
+ if ((parsed_function_.function().kind() == RawFunction::kImplicitSetter)) {
+ IntrinsifySetter();
+ return true;
+ }
+ }
+ // Even if an intrinsified version of the function was successfully
+ // generated, it may fall through to the non-intrinsified method body.
+ if (!FLAG_trace_functions) {
+ return Intrinsifier::Intrinsify(parsed_function_.function(), assembler_);
+ }
+ return false;
+}
+
+
// TODO(srdjan): Investigate where to put the argument type checks for
// checked mode.
void FlowGraphCompiler::CompileGraph() {
+ if (TryIntrinsify()) {
+ // Make it patchable: code must have a minimum code size, nop(2) increases
+ // the minimum code size appropriately.
+ __ nop(2);
+ __ int3();
+ __ jmp(&StubCode::FixCallersTargetLabel());
+ return;
+ }
// Specialized version of entry code from CodeGenerator::GenerateEntryCode.
const Function& function = parsed_function_.function();
« no previous file with comments | « runtime/vm/flow_graph_compiler_x64.h ('k') | runtime/vm/intrinsifier.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698