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

Side by Side Diff: vm/intermediate_language_x64.cc

Issue 10823228: Remove duplicate code for smi and double comparison from the compiler. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/runtime/
Patch Set: Created 8 years, 4 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 unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « vm/intermediate_language_ia32.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_X64. 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_X64.
6 #if defined(TARGET_ARCH_X64) 6 #if defined(TARGET_ARCH_X64)
7 7
8 #include "vm/intermediate_language.h" 8 #include "vm/intermediate_language.h"
9 9
10 #include "lib/error.h" 10 #include "lib/error.h"
(...skipping 250 matching lines...) Expand 10 before | Expand all | Expand 10 after
261 const intptr_t kNumTemps = 0; 261 const intptr_t kNumTemps = 0;
262 LocationSummary* locs = 262 LocationSummary* locs =
263 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); 263 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall);
264 locs->set_in(0, Location::RegisterLocation(RCX)); 264 locs->set_in(0, Location::RegisterLocation(RCX));
265 locs->set_in(1, Location::RegisterLocation(RDX)); 265 locs->set_in(1, Location::RegisterLocation(RDX));
266 locs->set_out(Location::RegisterLocation(RAX)); 266 locs->set_out(Location::RegisterLocation(RAX));
267 return locs; 267 return locs;
268 } 268 }
269 269
270 270
271 // Optional integer arguments can often be null. Null is not collected
272 // by IC data. TODO(srdjan): Shall we collect null classes in ICData as well?
273 static void EmitSmiEqualityCompare(FlowGraphCompiler* compiler,
274 EqualityCompareComp* comp) {
275 Register left = comp->locs()->in(0).reg();
276 Register right = comp->locs()->in(1).reg();
277 Register temp = comp->locs()->temp(0).reg();
278 Label* deopt = compiler->AddDeoptStub(comp->deopt_id(),
279 comp->token_pos(),
280 comp->try_index(),
281 kDeoptSmiCompareSmi,
282 left,
283 right);
284 __ movq(temp, left);
285 __ orq(temp, right);
286 __ testq(temp, Immediate(kSmiTagMask));
287 __ j(NOT_ZERO, deopt);
288 __ cmpq(left, right);
289 Register result = comp->locs()->out().reg();
290 Label load_true, done;
291 __ j(TokenKindToSmiCondition(comp->kind()), &load_true, Assembler::kNearJump);
292 __ LoadObject(result, compiler->bool_false());
293 __ jmp(&done, Assembler::kNearJump);
294 __ Bind(&load_true);
295 __ LoadObject(result, compiler->bool_true());
296 __ Bind(&done);
297 }
298
299
300 // TODO(srdjan): Add support for mixed Smi/Double equality
301 // (see LoadDoubleOrSmiToXmm).
302 static void EmitDoubleEqualityCompare(FlowGraphCompiler* compiler,
303 EqualityCompareComp* comp) {
304 Register left = comp->locs()->in(0).reg();
305 Register right = comp->locs()->in(1).reg();
306 Label* deopt = compiler->AddDeoptStub(comp->deopt_id(),
307 comp->token_pos(),
308 comp->try_index(),
309 kDeoptDoubleCompareDouble,
310 left,
311 right);
312 __ CompareClassId(left, kDouble);
313 __ j(NOT_EQUAL, deopt);
314 __ CompareClassId(right, kDouble);
315 __ j(NOT_EQUAL, deopt);
316 __ movsd(XMM0, FieldAddress(left, Double::value_offset()));
317 __ movsd(XMM1, FieldAddress(right, Double::value_offset()));
318 compiler->EmitDoubleCompareBool(TokenKindToSmiCondition(comp->kind()),
319 XMM0, XMM1,
320 comp->locs()->out().reg());
321 }
322
323
324 static void EmitEqualityAsInstanceCall(FlowGraphCompiler* compiler, 271 static void EmitEqualityAsInstanceCall(FlowGraphCompiler* compiler,
325 EqualityCompareComp* comp) { 272 EqualityCompareComp* comp) {
326 compiler->AddCurrentDescriptor(PcDescriptors::kDeopt, 273 compiler->AddCurrentDescriptor(PcDescriptors::kDeopt,
327 comp->deopt_id(), 274 comp->deopt_id(),
328 comp->token_pos(), 275 comp->token_pos(),
329 comp->try_index()); 276 comp->try_index());
330 const String& operator_name = String::ZoneHandle(Symbols::New("==")); 277 const String& operator_name = String::ZoneHandle(Symbols::New("=="));
331 const int kNumberOfArguments = 2; 278 const int kNumberOfArguments = 2;
332 const Array& kNoArgumentNames = Array::Handle(); 279 const Array& kNoArgumentNames = Array::Handle();
333 const int kNumArgumentsChecked = 2; 280 const int kNumArgumentsChecked = 2;
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after
481 __ jmp(&done); 428 __ jmp(&done);
482 __ Bind(&non_null_compare); // Receiver is not null. 429 __ Bind(&non_null_compare); // Receiver is not null.
483 __ pushq(left); 430 __ pushq(left);
484 __ pushq(right); 431 __ pushq(right);
485 EmitEqualityAsPolymorphicCall(compiler, ic_data, locs, branch, kind, 432 EmitEqualityAsPolymorphicCall(compiler, ic_data, locs, branch, kind,
486 deopt_id, token_pos, try_index); 433 deopt_id, token_pos, try_index);
487 __ Bind(&done); 434 __ Bind(&done);
488 } 435 }
489 436
490 437
491 void EqualityCompareComp::EmitNativeCode(FlowGraphCompiler* compiler) {
492 if (receiver_class_id() == kSmi) {
493 EmitSmiEqualityCompare(compiler, this);
494 return;
495 }
496 if (receiver_class_id() == kDouble) {
497 EmitDoubleEqualityCompare(compiler, this);
498 return;
499 }
500 if (HasICData() && (ic_data()->NumberOfChecks() > 0)) {
501 EmitGenericEqualityCompare(compiler, *locs(), kind(), NULL, *ic_data(),
502 deopt_id(), token_pos(), try_index());
503 } else {
504 Register left = locs()->in(0).reg();
505 Register right = locs()->in(1).reg();
506 __ pushq(left);
507 __ pushq(right);
508 EmitEqualityAsInstanceCall(compiler, this);
509 }
510 }
511
512
513 LocationSummary* RelationalOpComp::MakeLocationSummary() const {
514 if (operands_class_id() == kSmi || operands_class_id() == kDouble) {
515 const intptr_t kNumInputs = 2;
516 const intptr_t kNumTemps = 1;
517 LocationSummary* summary =
518 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
519 summary->set_in(0, Location::RequiresRegister());
520 summary->set_in(1, Location::RequiresRegister());
521 summary->set_out(Location::RequiresRegister());
522 summary->set_temp(0, Location::RequiresRegister());
523 return summary;
524 }
525 ASSERT(operands_class_id() == kObject);
526 return MakeCallSummary();
527 }
528
529
530 static void EmitSmiComparisonOp(FlowGraphCompiler* compiler, 438 static void EmitSmiComparisonOp(FlowGraphCompiler* compiler,
531 const LocationSummary& locs, 439 const LocationSummary& locs,
532 Token::Kind kind, 440 Token::Kind kind,
533 BranchInstr* branch, 441 BranchInstr* branch,
534 intptr_t deopt_id, 442 intptr_t deopt_id,
535 intptr_t token_pos, 443 intptr_t token_pos,
536 intptr_t try_index) { 444 intptr_t try_index) {
537 Register left = locs.in(0).reg(); 445 Register left = locs.in(0).reg();
538 Register right = locs.in(1).reg(); 446 Register right = locs.in(1).reg();
539 Register temp = locs.temp(0).reg(); 447 Register temp = locs.temp(0).reg();
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
605 if (branch != NULL) { 513 if (branch != NULL) {
606 compiler->EmitDoubleCompareBranch( 514 compiler->EmitDoubleCompareBranch(
607 true_condition, XMM0, XMM1, branch); 515 true_condition, XMM0, XMM1, branch);
608 } else { 516 } else {
609 compiler->EmitDoubleCompareBool( 517 compiler->EmitDoubleCompareBool(
610 true_condition, XMM0, XMM1, locs.out().reg()); 518 true_condition, XMM0, XMM1, locs.out().reg());
611 } 519 }
612 } 520 }
613 521
614 522
523 void EqualityCompareComp::EmitNativeCode(FlowGraphCompiler* compiler) {
524 if (receiver_class_id() == kSmi) {
525 EmitSmiComparisonOp(compiler, *locs(), kind(), NULL, // No branch.
526 deopt_id(), token_pos(), try_index());
527 return;
528 }
529 if (receiver_class_id() == kDouble) {
530 EmitDoubleComparisonOp(compiler, *locs(), kind(), NULL, // No branch.
531 deopt_id(), token_pos(), try_index());
532 return;
533 }
534 if (HasICData() && (ic_data()->NumberOfChecks() > 0)) {
535 EmitGenericEqualityCompare(compiler, *locs(), kind(), NULL, *ic_data(),
536 deopt_id(), token_pos(), try_index());
537 } else {
538 Register left = locs()->in(0).reg();
539 Register right = locs()->in(1).reg();
540 __ pushq(left);
541 __ pushq(right);
542 EmitEqualityAsInstanceCall(compiler, this);
543 }
544 }
545
546
547 LocationSummary* RelationalOpComp::MakeLocationSummary() const {
548 if (operands_class_id() == kSmi || operands_class_id() == kDouble) {
549 const intptr_t kNumInputs = 2;
550 const intptr_t kNumTemps = 1;
551 LocationSummary* summary =
552 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
553 summary->set_in(0, Location::RequiresRegister());
554 summary->set_in(1, Location::RequiresRegister());
555 summary->set_out(Location::RequiresRegister());
556 summary->set_temp(0, Location::RequiresRegister());
557 return summary;
558 }
559 ASSERT(operands_class_id() == kObject);
560 return MakeCallSummary();
561 }
562
563
615 void RelationalOpComp::EmitNativeCode(FlowGraphCompiler* compiler) { 564 void RelationalOpComp::EmitNativeCode(FlowGraphCompiler* compiler) {
616 if (operands_class_id() == kSmi) { 565 if (operands_class_id() == kSmi) {
617 EmitSmiComparisonOp(compiler, *locs(), kind(), NULL, 566 EmitSmiComparisonOp(compiler, *locs(), kind(), NULL,
618 deopt_id(), token_pos(), try_index()); 567 deopt_id(), token_pos(), try_index());
619 return; 568 return;
620 } 569 }
621 if (operands_class_id() == kDouble) { 570 if (operands_class_id() == kDouble) {
622 EmitDoubleComparisonOp(compiler, *locs(), kind(), NULL, 571 EmitDoubleComparisonOp(compiler, *locs(), kind(), NULL,
623 deopt_id(), token_pos(), try_index()); 572 deopt_id(), token_pos(), try_index());
624 return; 573 return;
(...skipping 1489 matching lines...) Expand 10 before | Expand all | Expand 10 after
2114 ASSERT(locs()->out().reg() == RAX); 2063 ASSERT(locs()->out().reg() == RAX);
2115 __ CompareObject(locs()->out().reg(), compiler->bool_true()); 2064 __ CompareObject(locs()->out().reg(), compiler->bool_true());
2116 EmitBranchOnCondition(compiler, branch_condition); 2065 EmitBranchOnCondition(compiler, branch_condition);
2117 } 2066 }
2118 2067
2119 } // namespace dart 2068 } // namespace dart
2120 2069
2121 #undef __ 2070 #undef __
2122 2071
2123 #endif // defined TARGET_ARCH_X64 2072 #endif // defined TARGET_ARCH_X64
OLDNEW
« no previous file with comments | « vm/intermediate_language_ia32.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698