| Index: runtime/vm/intermediate_language_arm.cc
|
| ===================================================================
|
| --- runtime/vm/intermediate_language_arm.cc (revision 19074)
|
| +++ runtime/vm/intermediate_language_arm.cc (working copy)
|
| @@ -16,6 +16,8 @@
|
| #include "vm/stub_code.h"
|
| #include "vm/symbols.h"
|
|
|
| +#define __ compiler->assembler()->
|
| +
|
| namespace dart {
|
|
|
| DECLARE_FLAG(int, optimization_counter_threshold);
|
| @@ -39,13 +41,43 @@
|
|
|
|
|
| LocationSummary* ReturnInstr::MakeLocationSummary() const {
|
| - UNIMPLEMENTED();
|
| - return NULL;
|
| + const intptr_t kNumInputs = 1;
|
| + const intptr_t kNumTemps = 0;
|
| + LocationSummary* locs =
|
| + new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall);
|
| + locs->set_in(0, Location::RegisterLocation(R0));
|
| + return locs;
|
| }
|
|
|
|
|
| +// Attempt optimized compilation at return instruction instead of at the entry.
|
| +// The entry needs to be patchable, no inlined objects are allowed in the area
|
| +// that will be overwritten by the patch instructions: a branch macro sequence.
|
| void ReturnInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
|
| - UNIMPLEMENTED();
|
| + Register result = locs()->in(0).reg();
|
| + ASSERT(result == R0);
|
| +#if defined(DEBUG)
|
| + // TODO(srdjan): Fix for functions with finally clause.
|
| + // A finally clause may leave a previously pushed return value if it
|
| + // has its own return instruction. Method that have finally are currently
|
| + // not optimized.
|
| + if (!compiler->HasFinally()) {
|
| + __ sub(R2, FP, ShifterOperand(SP));
|
| + // + 1 for saved PP.
|
| + __ CompareImmediate(R2, (compiler->StackSize() + 1) * kWordSize);
|
| + __ bkpt(0, NE);
|
| + }
|
| +#endif
|
| + AssemblerMacros::LeaveDartFrame(compiler->assembler());
|
| + __ Ret();
|
| +
|
| + // Generate 2 NOP instructions so that the debugger can patch the return
|
| + // pattern (1 instruction) with a call to the debug stub (3 instructions).
|
| + __ nop();
|
| + __ nop();
|
| + compiler->AddCurrentDescriptor(PcDescriptors::kReturn,
|
| + Isolate::kNoDeoptId,
|
| + token_pos());
|
| }
|
|
|
|
|
| @@ -78,13 +110,18 @@
|
|
|
|
|
| LocationSummary* ConstantInstr::MakeLocationSummary() const {
|
| - UNIMPLEMENTED();
|
| - return NULL;
|
| + return LocationSummary::Make(0,
|
| + Location::RequiresRegister(),
|
| + LocationSummary::kNoCall);
|
| }
|
|
|
|
|
| void ConstantInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
|
| - UNIMPLEMENTED();
|
| + // The register allocator drops constant definitions that have no uses.
|
| + if (!locs()->out().IsInvalid()) {
|
| + Register result = locs()->out().reg();
|
| + __ LoadObject(result, value());
|
| + }
|
| }
|
|
|
|
|
| @@ -364,13 +401,52 @@
|
|
|
|
|
| LocationSummary* CheckStackOverflowInstr::MakeLocationSummary() const {
|
| - UNIMPLEMENTED();
|
| - return NULL;
|
| + const intptr_t kNumInputs = 0;
|
| + const intptr_t kNumTemps = 0;
|
| + LocationSummary* summary =
|
| + new LocationSummary(kNumInputs,
|
| + kNumTemps,
|
| + LocationSummary::kCallOnSlowPath);
|
| + return summary;
|
| }
|
|
|
|
|
| +class CheckStackOverflowSlowPath : public SlowPathCode {
|
| + public:
|
| + explicit CheckStackOverflowSlowPath(CheckStackOverflowInstr* instruction)
|
| + : instruction_(instruction) { }
|
| +
|
| + virtual void EmitNativeCode(FlowGraphCompiler* compiler) {
|
| + __ Comment("CheckStackOverflowSlowPath");
|
| + __ Bind(entry_label());
|
| + compiler->SaveLiveRegisters(instruction_->locs());
|
| + // pending_deoptimization_env_ is needed to generate a runtime call that
|
| + // may throw an exception.
|
| + ASSERT(compiler->pending_deoptimization_env_ == NULL);
|
| + compiler->pending_deoptimization_env_ = instruction_->env();
|
| + compiler->GenerateCallRuntime(instruction_->token_pos(),
|
| + instruction_->deopt_id(),
|
| + kStackOverflowRuntimeEntry,
|
| + instruction_->locs());
|
| + compiler->pending_deoptimization_env_ = NULL;
|
| + compiler->RestoreLiveRegisters(instruction_->locs());
|
| + __ b(exit_label());
|
| + }
|
| +
|
| + private:
|
| + CheckStackOverflowInstr* instruction_;
|
| +};
|
| +
|
| +
|
| void CheckStackOverflowInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
|
| - UNIMPLEMENTED();
|
| + CheckStackOverflowSlowPath* slow_path = new CheckStackOverflowSlowPath(this);
|
| + compiler->AddSlowPathCode(slow_path);
|
| +
|
| + __ LoadImmediate(IP, Isolate::Current()->stack_limit_address());
|
| + __ ldr(IP, Address(IP));
|
| + __ cmp(SP, ShifterOperand(IP));
|
| + __ b(slow_path->entry_label(), LS);
|
| + __ Bind(slow_path->exit_label());
|
| }
|
|
|
|
|
|
|