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

Side by Side Diff: vm/intermediate_language_x64.cc

Issue 10828208: Revert r10379: "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 266 matching lines...) Expand 10 before | Expand all | Expand 10 after
277 const intptr_t kNumTemps = 0; 277 const intptr_t kNumTemps = 0;
278 LocationSummary* locs = 278 LocationSummary* locs =
279 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); 279 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall);
280 locs->set_in(0, Location::RegisterLocation(RCX)); 280 locs->set_in(0, Location::RegisterLocation(RCX));
281 locs->set_in(1, Location::RegisterLocation(RDX)); 281 locs->set_in(1, Location::RegisterLocation(RDX));
282 locs->set_out(Location::RegisterLocation(RAX)); 282 locs->set_out(Location::RegisterLocation(RAX));
283 return locs; 283 return locs;
284 } 284 }
285 285
286 286
287 // Optional integer arguments can often be null. Null is not collected
288 // by IC data. TODO(srdjan): Shall we collect null classes in ICData as well?
289 static void EmitSmiEqualityCompare(FlowGraphCompiler* compiler,
290 EqualityCompareComp* comp) {
291 Register left = comp->locs()->in(0).reg();
292 Register right = comp->locs()->in(1).reg();
293 Register temp = comp->locs()->temp(0).reg();
294 Label* deopt = compiler->AddDeoptStub(comp->deopt_id(),
295 comp->token_pos(),
296 comp->try_index(),
297 kDeoptSmiCompareSmi,
298 left,
299 right);
300 __ movq(temp, left);
301 __ orq(temp, right);
302 __ testq(temp, Immediate(kSmiTagMask));
303 __ j(NOT_ZERO, deopt);
304 __ cmpq(left, right);
305 Register result = comp->locs()->out().reg();
306 Label load_true, done;
307 __ j(TokenKindToSmiCondition(comp->kind()), &load_true, Assembler::kNearJump);
308 __ LoadObject(result, compiler->bool_false());
309 __ jmp(&done, Assembler::kNearJump);
310 __ Bind(&load_true);
311 __ LoadObject(result, compiler->bool_true());
312 __ Bind(&done);
313 }
314
315
316 // TODO(srdjan): Add support for mixed Smi/Double equality
317 // (see LoadDoubleOrSmiToXmm).
318 static void EmitDoubleEqualityCompare(FlowGraphCompiler* compiler,
319 EqualityCompareComp* comp) {
320 Register left = comp->locs()->in(0).reg();
321 Register right = comp->locs()->in(1).reg();
322 Label* deopt = compiler->AddDeoptStub(comp->deopt_id(),
323 comp->token_pos(),
324 comp->try_index(),
325 kDeoptDoubleCompareDouble,
326 left,
327 right);
328 __ CompareClassId(left, kDouble);
329 __ j(NOT_EQUAL, deopt);
330 __ CompareClassId(right, kDouble);
331 __ j(NOT_EQUAL, deopt);
332 __ movsd(XMM0, FieldAddress(left, Double::value_offset()));
333 __ movsd(XMM1, FieldAddress(right, Double::value_offset()));
334 compiler->EmitDoubleCompareBool(TokenKindToSmiCondition(comp->kind()),
335 XMM0, XMM1,
336 comp->locs()->out().reg());
337 }
338
339
287 static void EmitEqualityAsInstanceCall(FlowGraphCompiler* compiler, 340 static void EmitEqualityAsInstanceCall(FlowGraphCompiler* compiler,
288 EqualityCompareComp* comp) { 341 EqualityCompareComp* comp) {
289 compiler->AddCurrentDescriptor(PcDescriptors::kDeopt, 342 compiler->AddCurrentDescriptor(PcDescriptors::kDeopt,
290 comp->deopt_id(), 343 comp->deopt_id(),
291 comp->token_pos(), 344 comp->token_pos(),
292 comp->try_index()); 345 comp->try_index());
293 const String& operator_name = String::ZoneHandle(Symbols::New("==")); 346 const String& operator_name = String::ZoneHandle(Symbols::New("=="));
294 const int kNumberOfArguments = 2; 347 const int kNumberOfArguments = 2;
295 const Array& kNoArgumentNames = Array::Handle(); 348 const Array& kNoArgumentNames = Array::Handle();
296 const int kNumArgumentsChecked = 2; 349 const int kNumArgumentsChecked = 2;
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after
444 __ jmp(&done); 497 __ jmp(&done);
445 __ Bind(&non_null_compare); // Receiver is not null. 498 __ Bind(&non_null_compare); // Receiver is not null.
446 __ pushq(left); 499 __ pushq(left);
447 __ pushq(right); 500 __ pushq(right);
448 EmitEqualityAsPolymorphicCall(compiler, ic_data, locs, branch, kind, 501 EmitEqualityAsPolymorphicCall(compiler, ic_data, locs, branch, kind,
449 deopt_id, token_pos, try_index); 502 deopt_id, token_pos, try_index);
450 __ Bind(&done); 503 __ Bind(&done);
451 } 504 }
452 505
453 506
507 void EqualityCompareComp::EmitNativeCode(FlowGraphCompiler* compiler) {
508 if (receiver_class_id() == kSmi) {
509 EmitSmiEqualityCompare(compiler, this);
510 return;
511 }
512 if (receiver_class_id() == kDouble) {
513 EmitDoubleEqualityCompare(compiler, this);
514 return;
515 }
516 if (HasICData() && (ic_data()->NumberOfChecks() > 0)) {
517 EmitGenericEqualityCompare(compiler, *locs(), kind(), NULL, *ic_data(),
518 deopt_id(), token_pos(), try_index());
519 } else {
520 Register left = locs()->in(0).reg();
521 Register right = locs()->in(1).reg();
522 __ pushq(left);
523 __ pushq(right);
524 EmitEqualityAsInstanceCall(compiler, this);
525 }
526 }
527
528
529 LocationSummary* RelationalOpComp::MakeLocationSummary() const {
530 if (operands_class_id() == kSmi || operands_class_id() == kDouble) {
531 const intptr_t kNumInputs = 2;
532 const intptr_t kNumTemps = 1;
533 LocationSummary* summary =
534 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
535 summary->set_in(0, Location::RequiresRegister());
536 summary->set_in(1, Location::RequiresRegister());
537 summary->set_out(Location::RequiresRegister());
538 summary->set_temp(0, Location::RequiresRegister());
539 return summary;
540 }
541 ASSERT(operands_class_id() == kObject);
542 return MakeCallSummary();
543 }
544
545
454 static void EmitSmiComparisonOp(FlowGraphCompiler* compiler, 546 static void EmitSmiComparisonOp(FlowGraphCompiler* compiler,
455 const LocationSummary& locs, 547 const LocationSummary& locs,
456 Token::Kind kind, 548 Token::Kind kind,
457 BranchInstr* branch, 549 BranchInstr* branch,
458 intptr_t deopt_id, 550 intptr_t deopt_id,
459 intptr_t token_pos, 551 intptr_t token_pos,
460 intptr_t try_index) { 552 intptr_t try_index) {
461 Register left = locs.in(0).reg(); 553 Register left = locs.in(0).reg();
462 Register right = locs.in(1).reg(); 554 Register right = locs.in(1).reg();
463 Register temp = locs.temp(0).reg(); 555 Register temp = locs.temp(0).reg();
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
529 if (branch != NULL) { 621 if (branch != NULL) {
530 compiler->EmitDoubleCompareBranch( 622 compiler->EmitDoubleCompareBranch(
531 true_condition, XMM0, XMM1, branch); 623 true_condition, XMM0, XMM1, branch);
532 } else { 624 } else {
533 compiler->EmitDoubleCompareBool( 625 compiler->EmitDoubleCompareBool(
534 true_condition, XMM0, XMM1, locs.out().reg()); 626 true_condition, XMM0, XMM1, locs.out().reg());
535 } 627 }
536 } 628 }
537 629
538 630
539 void EqualityCompareComp::EmitNativeCode(FlowGraphCompiler* compiler) {
540 if (receiver_class_id() == kSmi) {
541 EmitSmiComparisonOp(compiler, *locs(), kind(), NULL, // No branch.
542 deopt_id(), token_pos(), try_index());
543 return;
544 }
545 if (receiver_class_id() == kDouble) {
546 EmitDoubleComparisonOp(compiler, *locs(), kind(), NULL, // No branch.
547 deopt_id(), token_pos(), try_index());
548 return;
549 }
550 if (HasICData() && (ic_data()->NumberOfChecks() > 0)) {
551 EmitGenericEqualityCompare(compiler, *locs(), kind(), NULL, *ic_data(),
552 deopt_id(), token_pos(), try_index());
553 } else {
554 Register left = locs()->in(0).reg();
555 Register right = locs()->in(1).reg();
556 __ pushq(left);
557 __ pushq(right);
558 EmitEqualityAsInstanceCall(compiler, this);
559 }
560 }
561
562
563 LocationSummary* RelationalOpComp::MakeLocationSummary() const {
564 if (operands_class_id() == kSmi || operands_class_id() == kDouble) {
565 const intptr_t kNumInputs = 2;
566 const intptr_t kNumTemps = 1;
567 LocationSummary* summary =
568 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
569 summary->set_in(0, Location::RequiresRegister());
570 summary->set_in(1, Location::RequiresRegister());
571 summary->set_out(Location::RequiresRegister());
572 summary->set_temp(0, Location::RequiresRegister());
573 return summary;
574 }
575 ASSERT(operands_class_id() == kObject);
576 return MakeCallSummary();
577 }
578
579
580 void RelationalOpComp::EmitNativeCode(FlowGraphCompiler* compiler) { 631 void RelationalOpComp::EmitNativeCode(FlowGraphCompiler* compiler) {
581 if (operands_class_id() == kSmi) { 632 if (operands_class_id() == kSmi) {
582 EmitSmiComparisonOp(compiler, *locs(), kind(), NULL, 633 EmitSmiComparisonOp(compiler, *locs(), kind(), NULL,
583 deopt_id(), token_pos(), try_index()); 634 deopt_id(), token_pos(), try_index());
584 return; 635 return;
585 } 636 }
586 if (operands_class_id() == kDouble) { 637 if (operands_class_id() == kDouble) {
587 EmitDoubleComparisonOp(compiler, *locs(), kind(), NULL, 638 EmitDoubleComparisonOp(compiler, *locs(), kind(), NULL,
588 deopt_id(), token_pos(), try_index()); 639 deopt_id(), token_pos(), try_index());
589 return; 640 return;
(...skipping 1489 matching lines...) Expand 10 before | Expand all | Expand 10 after
2079 ASSERT(locs()->out().reg() == RAX); 2130 ASSERT(locs()->out().reg() == RAX);
2080 __ CompareObject(locs()->out().reg(), compiler->bool_true()); 2131 __ CompareObject(locs()->out().reg(), compiler->bool_true());
2081 EmitBranchOnCondition(compiler, branch_condition); 2132 EmitBranchOnCondition(compiler, branch_condition);
2082 } 2133 }
2083 2134
2084 } // namespace dart 2135 } // namespace dart
2085 2136
2086 #undef __ 2137 #undef __
2087 2138
2088 #endif // defined TARGET_ARCH_X64 2139 #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