| Index: vm/intermediate_language_x64.cc
|
| ===================================================================
|
| --- vm/intermediate_language_x64.cc (revision 7834)
|
| +++ vm/intermediate_language_x64.cc (working copy)
|
| @@ -7,12 +7,34 @@
|
|
|
| #include "vm/flow_graph_compiler.h"
|
| #include "vm/locations.h"
|
| +#include "vm/stub_code.h"
|
|
|
| #define __ compiler->assembler()->
|
|
|
| namespace dart {
|
|
|
|
|
| +// 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) {
|
| + Value* val = comp->ArgumentAt(i);
|
| + if (!val->IsUse()) return false;
|
| + intptr_t current = val->AsUse()->definition()->temp_index();
|
| + if (i != 0) {
|
| + if (current != (previous + 1)) return false;
|
| + }
|
| + previous = current;
|
| + }
|
| + return true;
|
| +}
|
| +
|
| +
|
| static LocationSummary* MakeSimpleLocationSummary(
|
| intptr_t input_count, Location out) {
|
| LocationSummary* summary = new LocationSummary(input_count);
|
| @@ -52,6 +74,71 @@
|
| }
|
|
|
|
|
| +// Generic summary for call instructions that have all arguments pushed
|
| +// on the stack and return the result in a fixed register RAX.
|
| +static LocationSummary* MakeCallSummary() {
|
| + LocationSummary* result = new LocationSummary(0);
|
| + result->set_out(Location::RegisterLocation(RAX));
|
| + return result;
|
| +}
|
| +
|
| +
|
| +LocationSummary* ClosureCallComp::MakeLocationSummary() {
|
| + return MakeCallSummary();
|
| +}
|
| +
|
| +
|
| +void ClosureCallComp::EmitNativeCode(FlowGraphCompiler* compiler) {
|
| + ASSERT(VerifyCallComputation(this));
|
| + // The arguments to the stub include the closure. The arguments
|
| + // descriptor describes the closure's arguments (and so does not include
|
| + // the closure).
|
| + int argument_count = ArgumentCount();
|
| + const Array& arguments_descriptor =
|
| + CodeGenerator::ArgumentsDescriptor(argument_count - 1,
|
| + argument_names());
|
| + __ LoadObject(R10, arguments_descriptor);
|
| +
|
| + compiler->GenerateCall(token_index(),
|
| + try_index(),
|
| + &StubCode::CallClosureFunctionLabel(),
|
| + PcDescriptors::kOther);
|
| + __ Drop(argument_count);
|
| +}
|
| +
|
| +
|
| +LocationSummary* InstanceCallComp::MakeLocationSummary() {
|
| + return MakeCallSummary();
|
| +}
|
| +
|
| +
|
| +void InstanceCallComp::EmitNativeCode(FlowGraphCompiler* compiler) {
|
| + ASSERT(VerifyCallComputation(this));
|
| + compiler->EmitInstanceCall(cid(),
|
| + token_index(),
|
| + try_index(),
|
| + function_name(),
|
| + ArgumentCount(),
|
| + argument_names(),
|
| + checked_argument_count());
|
| +}
|
| +
|
| +
|
| +LocationSummary* StaticCallComp::MakeLocationSummary() {
|
| + return MakeCallSummary();
|
| +}
|
| +
|
| +
|
| +void StaticCallComp::EmitNativeCode(FlowGraphCompiler* compiler) {
|
| + ASSERT(VerifyCallComputation(this));
|
| + compiler->EmitStaticCall(token_index(),
|
| + try_index(),
|
| + function(),
|
| + ArgumentCount(),
|
| + argument_names());
|
| +}
|
| +
|
| +
|
| void BindInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
|
| computation()->EmitNativeCode(compiler);
|
| __ pushq(locs()->out().reg());
|
|
|