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

Unified Diff: runtime/vm/flow_graph_compiler_x64.cc

Issue 9570015: Support instance getters and setters, indexed loads and stores. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: 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
« no previous file with comments | « runtime/vm/flow_graph_compiler_x64.h ('k') | runtime/vm/intermediate_language.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
diff --git a/runtime/vm/flow_graph_compiler_x64.cc b/runtime/vm/flow_graph_compiler_x64.cc
index 1a2ce75b591e3bd89505fa9e548c53706300e13a..05f21eb426556f9aa1f87108046ed1fb4a85e682 100644
--- a/runtime/vm/flow_graph_compiler_x64.cc
+++ b/runtime/vm/flow_graph_compiler_x64.cc
@@ -52,12 +52,12 @@ void FlowGraphCompiler::LoadValue(Value* value) {
void FlowGraphCompiler::VisitTemp(TempVal* val) {
- Bailout("TempVal");
+ LoadValue(val);
}
void FlowGraphCompiler::VisitConstant(ConstantVal* val) {
- Bailout("ConstantVal");
+ LoadValue(val);
}
@@ -66,8 +66,68 @@ void FlowGraphCompiler::VisitAssertAssignable(AssertAssignableComp* comp) {
}
+// True iff. the arguments to a call will be properly pushed and can
+// be popped after the call.
+template <typename T> static bool VerifyCallComputation(T* comp) {
+ // Argument values should be consecutive temps.
+ //
+ // TODO(kmillikin): implement stack height tracking so we can also assert
+ // they are on top of the stack.
+ intptr_t previous = -1;
+ for (int i = 0; i < comp->ArgumentCount(); ++i) {
+ TempVal* temp = comp->ArgumentAt(i)->AsTemp();
+ if (temp == NULL) return false;
+ if (i != 0) {
+ if (temp->index() != previous + 1) return false;
+ }
+ previous = temp->index();
+ }
+ return true;
srdjan 2012/03/01 23:19:31 Can you check that last temp is on TOS, i.e., with
Kevin Millikin (Google) 2012/03/02 09:01:28 We can't easily check that it's actually on top of
+}
+
+
+void FlowGraphCompiler::EmitInstanceCall(intptr_t node_id,
+ intptr_t token_index,
+ const String& function_name,
+ intptr_t argument_count,
+ const Array& argument_names,
+ intptr_t checked_argument_count) {
+ ICData& ic_data =
+ ICData::ZoneHandle(ICData::New(parsed_function_.function(),
+ function_name,
+ node_id,
+ checked_argument_count));
+ const Array& arguments_descriptor =
+ CodeGenerator::ArgumentsDescriptor(argument_count, argument_names);
+ __ LoadObject(RBX, ic_data);
+ __ LoadObject(R10, arguments_descriptor);
+
+ uword label_address = 0;
+ switch (checked_argument_count) {
+ case 1:
+ label_address = StubCode::OneArgCheckInlineCacheEntryPoint();
+ break;
+ case 2:
+ label_address = StubCode::TwoArgsCheckInlineCacheEntryPoint();
+ break;
+ default:
+ UNIMPLEMENTED();
+ }
+ ExternalLabel target_label("InlineCache", label_address);
+ __ call(&target_label);
+ AddCurrentDescriptor(PcDescriptors::kIcCall, node_id, token_index);
+ __ addq(RSP, Immediate(argument_count * kWordSize));
+}
+
+
void FlowGraphCompiler::VisitInstanceCall(InstanceCallComp* comp) {
- Bailout("InstanceCallComp");
+ ASSERT(VerifyCallComputation(comp));
+ EmitInstanceCall(comp->node_id(),
+ comp->token_index(),
+ comp->function_name(),
+ comp->ArgumentCount(),
+ comp->argument_names(),
+ comp->checked_argument_count());
}
@@ -78,7 +138,19 @@ void FlowGraphCompiler::VisitStrictCompare(StrictCompareComp* comp) {
void FlowGraphCompiler::VisitStaticCall(StaticCallComp* comp) {
- Bailout("StaticCallComp");
+ ASSERT(VerifyCallComputation(comp));
+
+ int argument_count = comp->ArgumentCount();
+ const Array& arguments_descriptor =
+ CodeGenerator::ArgumentsDescriptor(argument_count,
+ comp->argument_names());
+ __ LoadObject(RBX, comp->function());
+ __ LoadObject(R10, arguments_descriptor);
+
+ GenerateCall(comp->token_index(),
+ &StubCode::CallStaticFunctionLabel(),
+ PcDescriptors::kFuncCall);
+ __ addq(RSP, Immediate(argument_count * kWordSize));
}
@@ -99,6 +171,36 @@ void FlowGraphCompiler::VisitStoreLocal(StoreLocalComp* comp) {
}
+void FlowGraphCompiler::VisitStoreIndexed(StoreIndexedComp* comp) {
+ // Call operator []= but preserve the third argument value under the
+ // arguments as the result of the computation.
+ const String& function_name =
+ String::ZoneHandle(String::NewSymbol(Token::Str(Token::kASSIGN_INDEX)));
+ // Placeholder is under value, index, and receiver.
+ const int kPlaceholderOffset = 3 * kWordSize;
+ __ movq(RAX, Address(RSP, 0)); // Value.
+ __ movq(Address(RSP, kPlaceholderOffset), RAX);
+ EmitInstanceCall(comp->node_id(), comp->token_index(), function_name, 3,
+ Array::ZoneHandle(), 1);
+ __ popq(RAX);
+}
+
+
+void FlowGraphCompiler::VisitInstanceSetter(InstanceSetterComp* comp) {
+ // Preserve the second argument under the arguments as the result of the
+ // computation, then call the getter.
srdjan 2012/03/01 23:19:31 Can you verify that place holder, value, array and
Kevin Millikin (Google) 2012/03/02 09:01:28 Yes.
+ const String& function_name =
+ String::ZoneHandle(Field::SetterSymbol(comp->field_name()));
+ // Placeholder is under value and receiver.
+ const int kPlaceholderOffset = 2 * kWordSize;
+ __ movq(RAX, Address(RSP, 0)); // Value.
+ __ movq(Address(RSP, kPlaceholderOffset), RAX);
+ EmitInstanceCall(comp->node_id(), comp->token_index(), function_name, 2,
+ Array::ZoneHandle(), 1);
+ __ popq(RAX);
+}
+
+
void FlowGraphCompiler::VisitJoinEntry(JoinEntryInstr* instr) {
Bailout("JoinEntryInstr");
}
@@ -258,6 +360,14 @@ void FlowGraphCompiler::CompileGraph() {
// Infrastructure copied from class CodeGenerator.
+void FlowGraphCompiler::GenerateCall(intptr_t token_index,
+ const ExternalLabel* label,
+ PcDescriptors::Kind kind) {
+ __ call(label);
+ AddCurrentDescriptor(kind, AstNode::kNoId, token_index);
+}
+
+
void FlowGraphCompiler::GenerateCallRuntime(intptr_t node_id,
intptr_t token_index,
const RuntimeEntry& entry) {
« no previous file with comments | « runtime/vm/flow_graph_compiler_x64.h ('k') | runtime/vm/intermediate_language.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698