| Index: runtime/vm/intermediate_language_mips.cc
|
| ===================================================================
|
| --- runtime/vm/intermediate_language_mips.cc (revision 20729)
|
| +++ runtime/vm/intermediate_language_mips.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,49 @@
|
|
|
|
|
| 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(V0));
|
| + 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 == V0);
|
| +#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()) {
|
| + Label stack_ok;
|
| + __ Comment("Stack Check");
|
| + const int sp_fp_dist = compiler->StackSize() + (-kFirstLocalSlotIndex - 1);
|
| + __ subu(T2, FP, SP);
|
| +
|
| + __ addiu(T2, T2, Immediate(-sp_fp_dist * kWordSize));
|
| + __ beq(T2, ZR, &stack_ok);
|
| + __ break_(0);
|
| +
|
| + __ Bind(&stack_ok);
|
| + }
|
| +#endif
|
| + __ LeaveDartFrame();
|
| + __ 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 +116,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());
|
| + }
|
| }
|
|
|
|
|
| @@ -386,13 +429,54 @@
|
|
|
|
|
| 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(TMP, Isolate::Current()->stack_limit_address());
|
| +
|
| + __ lw(TMP, Address(TMP));
|
| + __ subu(TMP, SP, TMP);
|
| + __ blez(TMP, slow_path->entry_label());
|
| +
|
| + __ Bind(slow_path->exit_label());
|
| }
|
|
|
|
|
|
|