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

Unified Diff: runtime/vm/flow_graph_compiler_x64.cc

Issue 9447102: Implement x64 compilation for loading and storing local variables. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Bugfix and rebase to HEAD. Created 8 years, 10 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
Index: runtime/vm/flow_graph_compiler_x64.cc
diff --git a/runtime/vm/flow_graph_compiler_x64.cc b/runtime/vm/flow_graph_compiler_x64.cc
index ef95acc1583b92e11aaad9c6248c6ba32a94efe7..c0c496e2bbd7483468b238f406b120c5e2aee5d1 100644
--- a/runtime/vm/flow_graph_compiler_x64.cc
+++ b/runtime/vm/flow_graph_compiler_x64.cc
@@ -22,11 +22,12 @@ DECLARE_FLAG(bool, trace_functions);
DECLARE_FLAG(bool, disassemble);
void FlowGraphCompiler::Bailout(const char* reason) {
- const char* kFormat = "FlowGraphCompiler Bailout: %s.";
- intptr_t len = OS::SNPrint(NULL, 0, kFormat, reason) + 1;
+ const char* kFormat = "FlowGraphCompiler Bailout: %s %s.";
+ const char* function_name = parsed_function_.function().ToCString();
srdjan 2012/02/27 23:23:53 ToFullyQUalifiedCString if needed.
+ intptr_t len = OS::SNPrint(NULL, 0, kFormat, function_name, reason) + 1;
char* chars = reinterpret_cast<char*>(
Isolate::Current()->current_zone()->Allocate(len));
- OS::SNPrint(chars, len, kFormat, reason);
+ OS::SNPrint(chars, len, kFormat, function_name, reason);
const Error& error = Error::Handle(
LanguageError::New(String::Handle(String::New(chars))));
Isolate::Current()->long_jump_base()->Jump(1, error);
@@ -37,7 +38,7 @@ void FlowGraphCompiler::Bailout(const char* reason) {
void FlowGraphCompiler::LoadValue(Value* value) {
if (value->IsConstant()) {
- ConstantValue* constant = value->AsConstant();
+ ConstantVal* constant = value->AsConstant();
if (constant->instance().IsSmi()) {
int64_t imm = reinterpret_cast<int64_t>(constant->instance().raw());
__ movq(RAX, Immediate(imm));
@@ -46,11 +47,59 @@ void FlowGraphCompiler::LoadValue(Value* value) {
}
} else {
ASSERT(value->IsTemp());
- Bailout("return of non-ConstantValue value");
+ __ popq(RAX);
}
}
+void FlowGraphCompiler::VisitTemp(TempVal* val) {
+ Bailout("TempVal");
+}
+
+
+void FlowGraphCompiler::VisitConstant(ConstantVal* val) {
+ Bailout("ConstantVal");
+}
+
+
+void FlowGraphCompiler::VisitAssertAssignable(AssertAssignableComp* comp) {
+ Bailout("AssertAssignableComp");
+}
+
+
+void FlowGraphCompiler::VisitInstanceCall(InstanceCallComp* comp) {
+ Bailout("InstanceCallComp");
+}
+
+
+void FlowGraphCompiler::VisitStrictCompare(StrictCompareComp* comp) {
+ Bailout("StrictCompareComp");
+}
+
+
+
+void FlowGraphCompiler::VisitStaticCall(StaticCallComp* comp) {
+ Bailout("StaticCallComp");
+}
+
+
+void FlowGraphCompiler::VisitLoadLocal(LoadLocalComp* comp) {
+ if (comp->local().is_captured()) {
+ Bailout("load of context variable");
+ }
+ __ movq(RAX, Address(RBP, comp->local().index() * kWordSize));
+}
+
+
+void FlowGraphCompiler::VisitStoreLocal(StoreLocalComp* comp) {
+ if (comp->local().is_captured()) {
+ Bailout("store to context variable");
+ }
+ LoadValue(comp->value());
+ __ movq(Address(RBP, comp->local().index() * kWordSize), RAX);
+}
+
+
void FlowGraphCompiler::VisitJoinEntry(JoinEntryInstr* instr) {
Bailout("JoinEntryInstr");
}
@@ -62,12 +111,13 @@ void FlowGraphCompiler::VisitTargetEntry(TargetEntryInstr* instr) {
void FlowGraphCompiler::VisitDo(DoInstr* instr) {
- Bailout("DoInstr");
+ instr->computation()->Accept(this);
}
void FlowGraphCompiler::VisitBind(BindInstr* instr) {
- Bailout("DoInstr");
+ instr->computation()->Accept(this);
+ __ pushq(RAX);
}
@@ -76,10 +126,9 @@ void FlowGraphCompiler::VisitReturn(ReturnInstr* instr) {
#ifdef DEBUG
// Check that the entry stack size matches the exit stack size.
- const intptr_t locals_space_size = 0;
__ movq(R10, RBP);
__ subq(R10, RSP);
- __ cmpq(R10, Immediate(locals_space_size));
+ __ cmpq(R10, Immediate(stack_local_count() * kWordSize));
Label stack_ok;
__ j(EQUAL, &stack_ok, Assembler::kNearJump);
__ Stop("Exit stack size does not match the entry stack size.");
@@ -104,23 +153,19 @@ void FlowGraphCompiler::VisitReturn(ReturnInstr* instr) {
void FlowGraphCompiler::VisitBranch(BranchInstr* instr) {
- Bailout("VisitBranch");
+ Bailout("BranchInstr");
}
void FlowGraphCompiler::CompileGraph() {
const Function& function = parsed_function_.function();
- if ((function.num_fixed_parameters() != 0) ||
- (function.num_optional_parameters() != 0)) {
- Bailout("function has parameters");
+ if ((function.num_optional_parameters() != 0)) {
+ Bailout("function has optional parameters");
}
LocalScope* scope = parsed_function_.node_sequence()->scope();
- if (scope->child() != NULL) {
- Bailout("function has local scopes");
- }
LocalScope* context_owner = NULL;
- const int first_parameter_index = 1;
- const int parameter_count = 0;
+ const int parameter_count = function.num_fixed_parameters();
+ const int first_parameter_index = 1 + parameter_count;
const int first_local_index = -1;
int first_free_frame_index =
scope->AllocateVariables(first_parameter_index,
@@ -128,13 +173,12 @@ void FlowGraphCompiler::CompileGraph() {
first_local_index,
scope,
&context_owner);
- const int local_count = first_local_index - first_free_frame_index;
- if (local_count != 0) Bailout("function has locals");
+ set_stack_local_count(first_local_index - first_free_frame_index);
if (blocks_->length() != 1) Bailout("more than 1 basic block");
// Specialized version of entry code from CodeGenerator::GenerateEntryCode.
- __ EnterFrame(0);
+ __ EnterFrame(stack_local_count() * kWordSize);
#ifdef DEBUG
const bool check_arguments = true;
#else
@@ -145,7 +189,7 @@ void FlowGraphCompiler::CompileGraph() {
Label argc_in_range;
// Total number of args is the first Smi in args descriptor array (R10).
__ movq(RAX, FieldAddress(R10, Array::data_offset()));
- __ cmpq(RAX, Immediate(Smi::RawValue(0)));
+ __ cmpq(RAX, Immediate(Smi::RawValue(parameter_count)));
__ j(EQUAL, &argc_in_range, Assembler::kNearJump);
if (function.IsClosureFunction()) {
GenerateCallRuntime(AstNode::kNoId,
@@ -156,11 +200,21 @@ void FlowGraphCompiler::CompileGraph() {
}
__ Bind(&argc_in_range);
}
+
+ // Initialize locals to null.
srdjan 2012/02/27 23:23:53 Shall we generate IL to describe the NULL stores i
Kevin Millikin (Google) 2012/02/28 09:13:12 It looks like they're already present in the AST,
+ if (stack_local_count() > 0) {
+ __ movq(RAX, Immediate(reinterpret_cast<intptr_t>(Object::null())));
+ for (int i = 0; i < stack_local_count(); ++i) {
+ // Subtract index i (locals lie at lower addresses than RBP).
+ __ movq(Address(RBP, (first_local_index - i) * kWordSize), RAX);
+ }
+ }
+
// Generate stack overflow check.
__ movq(TMP, Immediate(Isolate::Current()->stack_limit_address()));
__ cmpq(RSP, Address(TMP, 0));
Label no_stack_overflow;
- __ j(ABOVE, &no_stack_overflow);
+ __ j(ABOVE, &no_stack_overflow, Assembler::kNearJump);
GenerateCallRuntime(AstNode::kNoId,
function.token_index(),
kStackOverflowRuntimeEntry);

Powered by Google App Engine
This is Rietveld 408576698