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

Unified Diff: runtime/vm/intermediate_language_x64.cc

Issue 10536086: Add stack check in loops so that loops can be stopped. Optimize relational operations. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 years, 6 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/intermediate_language_ia32.cc ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: runtime/vm/intermediate_language_x64.cc
===================================================================
--- runtime/vm/intermediate_language_x64.cc (revision 8493)
+++ runtime/vm/intermediate_language_x64.cc (working copy)
@@ -242,6 +242,149 @@
}
+static Condition TokenKindToSmiCondition(Token::Kind kind) {
+ switch (kind) {
+ case Token::kEQ: return EQUAL;
+ case Token::kNE: return NOT_EQUAL;
+ case Token::kLT: return LESS;
+ case Token::kGT: return GREATER;
+ case Token::kLTE: return LESS_EQUAL;
+ case Token::kGTE: return GREATER_EQUAL;
+ default:
+ UNREACHABLE();
+ return OVERFLOW;
+ }
+}
+
+
+static void EmitSmiRelationalOp(FlowGraphCompiler* compiler,
+ RelationalOpComp* comp) {
+ Register left = comp->locs()->in(0).reg();
+ Register right = comp->locs()->in(1).reg();
+ Register result = comp->locs()->out().reg();
+ Label* deopt = compiler->AddDeoptStub(comp->cid(),
+ comp->token_index(),
+ comp->try_index(),
+ kDeoptSmiCompareSmis,
+ left,
+ right);
+ __ movq(TMP, left);
+ __ orq(TMP, right);
+ __ testq(TMP, Immediate(kSmiTagMask));
+ __ j(NOT_ZERO, deopt);
+ const Bool& bool_true = Bool::ZoneHandle(Bool::True());
+ const Bool& bool_false = Bool::ZoneHandle(Bool::False());
+ Condition condition = TokenKindToSmiCondition(comp->kind());
+
+ Label done, is_true;
+ __ cmpq(left, right);
+ __ j(condition, &is_true);
+ __ LoadObject(result, bool_false);
+ __ jmp(&done);
+ __ Bind(&is_true);
+ __ LoadObject(result, bool_true);
+ __ Bind(&done);
+}
+
+
+LocationSummary* RelationalOpComp::MakeLocationSummary() const {
+ if (operands_class_id() == kSmi) {
+ const intptr_t kNumInputs = 2;
+ const intptr_t kNumTemps = 0;
+ LocationSummary* summary = new LocationSummary(kNumInputs, kNumTemps);
+ summary->set_in(0, Location::RequiresRegister());
+ summary->set_in(1, Location::RequiresRegister());
+ summary->set_out(Location::RequiresRegister());
+ return summary;
+ }
+ if (operands_class_id() == kDouble) {
+ const intptr_t kNumInputs = 2;
+ const intptr_t kNumTemps = 1;
+ LocationSummary* summary = new LocationSummary(kNumInputs, kNumTemps);
+ summary->set_in(0, Location::RequiresRegister());
+ summary->set_in(1, Location::RequiresRegister());
+ summary->set_out(Location::RequiresRegister());
+ summary->set_temp(0, Location::RequiresRegister());
+ return summary;
+ }
+ ASSERT(operands_class_id() == kObject);
+ return MakeCallSummary();
+}
+
+
+
+static Condition TokenKindToDoubleCondition(Token::Kind kind) {
+ switch (kind) {
+ case Token::kEQ: return EQUAL;
+ case Token::kLT: return BELOW;
+ case Token::kGT: return ABOVE;
+ case Token::kLTE: return BELOW_EQUAL;
+ default:
+ UNREACHABLE();
+ return OVERFLOW;
+ }
+}
+
+
+static void EmitDoubleRelationalOp(FlowGraphCompiler* compiler,
+ RelationalOpComp* comp) {
+ Register left = comp->locs()->in(0).reg();
+ Register right = comp->locs()->in(1).reg();
+ Register result = comp->locs()->out().reg();
+ // TODO(srdjan): temp is only needed if a conversion Smi->Double occurs.
+ Register temp = comp->locs()->temp(0).reg();
+ Label* deopt = compiler->AddDeoptStub(comp->cid(),
+ comp->token_index(),
+ comp->try_index(),
+ kDeoptDoubleComparison,
+ left,
+ right);
+ compiler->LoadDoubleOrSmiToXmm(XMM0, left, temp, deopt);
+ compiler->LoadDoubleOrSmiToXmm(XMM1, right, temp, deopt);
+ const Bool& bool_true = Bool::ZoneHandle(Bool::True());
+ const Bool& bool_false = Bool::ZoneHandle(Bool::False());
+ Condition true_condition = TokenKindToDoubleCondition(comp->kind());
+ Label is_false, is_true, done;
+ __ comisd(XMM0, XMM1);
+ __ j(PARITY_EVEN, &is_false, Assembler::kNearJump); // NaN -> false;
+ __ j(true_condition, &is_true, Assembler::kNearJump);
+ __ Bind(&is_false);
+ __ LoadObject(result, bool_false);
+ __ jmp(&done);
+ __ Bind(&is_true);
+ __ LoadObject(result, bool_true);
+ __ Bind(&done);
+}
+
+
+void RelationalOpComp::EmitNativeCode(FlowGraphCompiler* compiler) {
+ if (operands_class_id() == kSmi) {
+ EmitSmiRelationalOp(compiler, this);
+ return;
+ }
+ if (operands_class_id() == kDouble) {
+ EmitDoubleRelationalOp(compiler, this);
+ return;
+ }
+ const String& function_name =
+ String::ZoneHandle(String::NewSymbol(Token::Str(kind())));
+ compiler->AddCurrentDescriptor(PcDescriptors::kDeopt,
+ cid(),
+ token_index(),
+ try_index());
+ const intptr_t kNumArguments = 2;
+ const intptr_t kNumArgsChecked = 2; // Type-feedback.
+ compiler->GenerateInstanceCall(cid(),
+ token_index(),
+ try_index(),
+ function_name,
+ kNumArguments,
+ Array::ZoneHandle(), // No optional arguments.
+ kNumArgsChecked);
+ ASSERT(locs()->out().reg() == RAX);
+}
+
+
LocationSummary* NativeCallComp::MakeLocationSummary() const {
LocationSummary* locs = new LocationSummary(0, 3);
locs->set_temp(0, Location::RegisterLocation(RAX));
@@ -864,6 +1007,30 @@
}
+LocationSummary* CheckStackOverflowComp::MakeLocationSummary() const {
+ const intptr_t kNumInputs = 0;
+ const intptr_t kNumTemps = 1;
+ LocationSummary* summary = new LocationSummary(kNumInputs, kNumTemps);
+ summary->set_temp(0, Location::RequiresRegister());
+ return summary;
+}
+
+
+void CheckStackOverflowComp::EmitNativeCode(FlowGraphCompiler* compiler) {
+ Register temp = comp->locs()->temp(0).reg();
+ // Generate stack overflow check.
+ __ movq(temp, Immediate(Isolate::Current()->stack_limit_address()));
+ __ cmpq(RSP, Address(temp, 0));
+ Label no_stack_overflow;
+ __ j(ABOVE, &no_stack_overflow, Assembler::kNearJump);
+ compiler->GenerateCallRuntime(cid(),
+ token_index(),
+ try_index(),
+ kStackOverflowRuntimeEntry);
+ __ Bind(&no_stack_overflow);
+}
+
+
LocationSummary* BinaryOpComp::MakeLocationSummary() const {
const intptr_t kNumInputs = 2;
« no previous file with comments | « runtime/vm/intermediate_language_ia32.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698