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

Side by Side Diff: vm/intermediate_language_x64.cc

Issue 10855050: Reapply and fix "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 234 matching lines...) Expand 10 before | Expand all | Expand 10 after
245 UNREACHABLE(); 245 UNREACHABLE();
246 return OVERFLOW; 246 return OVERFLOW;
247 } 247 }
248 } 248 }
249 249
250 250
251 LocationSummary* EqualityCompareComp::MakeLocationSummary() const { 251 LocationSummary* EqualityCompareComp::MakeLocationSummary() const {
252 const intptr_t kNumInputs = 2; 252 const intptr_t kNumInputs = 2;
253 if (receiver_class_id() != kObject) { 253 if (receiver_class_id() != kObject) {
254 ASSERT((receiver_class_id() == kSmi) || (receiver_class_id() == kDouble)); 254 ASSERT((receiver_class_id() == kSmi) || (receiver_class_id() == kDouble));
255 // No temporary register needed for double comparison. 255 const intptr_t kNumTemps = 1;
256 const intptr_t kNumTemps = (receiver_class_id() == kSmi) ? 1 : 0;
257 LocationSummary* locs = 256 LocationSummary* locs =
258 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 257 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
259 locs->set_in(0, Location::RequiresRegister()); 258 locs->set_in(0, Location::RequiresRegister());
260 locs->set_in(1, Location::RequiresRegister()); 259 locs->set_in(1, Location::RequiresRegister());
261 if (receiver_class_id() == kSmi) { 260 locs->set_temp(0, Location::RequiresRegister());
262 locs->set_temp(0, Location::RequiresRegister());
263 }
264 locs->set_out(Location::RequiresRegister()); 261 locs->set_out(Location::RequiresRegister());
265 return locs; 262 return locs;
266 } 263 }
267 if (HasICData() && (ic_data()->NumberOfChecks() > 0)) { 264 if (HasICData() && (ic_data()->NumberOfChecks() > 0)) {
268 const intptr_t kNumTemps = 1; 265 const intptr_t kNumTemps = 1;
269 LocationSummary* locs = 266 LocationSummary* locs =
270 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); 267 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall);
271 locs->set_in(0, Location::RegisterLocation(RCX)); 268 locs->set_in(0, Location::RegisterLocation(RCX));
272 locs->set_in(1, Location::RegisterLocation(RDX)); 269 locs->set_in(1, Location::RegisterLocation(RDX));
273 locs->set_temp(0, Location::RegisterLocation(RBX)); 270 locs->set_temp(0, Location::RegisterLocation(RBX));
274 locs->set_out(Location::RegisterLocation(RAX)); 271 locs->set_out(Location::RegisterLocation(RAX));
275 return locs; 272 return locs;
276 } 273 }
277 const intptr_t kNumTemps = 0; 274 const intptr_t kNumTemps = 0;
278 LocationSummary* locs = 275 LocationSummary* locs =
279 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); 276 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall);
280 locs->set_in(0, Location::RegisterLocation(RCX)); 277 locs->set_in(0, Location::RegisterLocation(RCX));
281 locs->set_in(1, Location::RegisterLocation(RDX)); 278 locs->set_in(1, Location::RegisterLocation(RDX));
282 locs->set_out(Location::RegisterLocation(RAX)); 279 locs->set_out(Location::RegisterLocation(RAX));
283 return locs; 280 return locs;
284 } 281 }
285 282
286 283
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
340 static void EmitEqualityAsInstanceCall(FlowGraphCompiler* compiler, 284 static void EmitEqualityAsInstanceCall(FlowGraphCompiler* compiler,
341 EqualityCompareComp* comp) { 285 EqualityCompareComp* comp) {
342 compiler->AddCurrentDescriptor(PcDescriptors::kDeopt, 286 compiler->AddCurrentDescriptor(PcDescriptors::kDeopt,
343 comp->deopt_id(), 287 comp->deopt_id(),
344 comp->token_pos(), 288 comp->token_pos(),
345 comp->try_index()); 289 comp->try_index());
346 const String& operator_name = String::ZoneHandle(Symbols::New("==")); 290 const String& operator_name = String::ZoneHandle(Symbols::New("=="));
347 const int kNumberOfArguments = 2; 291 const int kNumberOfArguments = 2;
348 const Array& kNoArgumentNames = Array::Handle(); 292 const Array& kNoArgumentNames = Array::Handle();
349 const int kNumArgumentsChecked = 2; 293 const int kNumArgumentsChecked = 2;
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after
497 __ jmp(&done); 441 __ jmp(&done);
498 __ Bind(&non_null_compare); // Receiver is not null. 442 __ Bind(&non_null_compare); // Receiver is not null.
499 __ pushq(left); 443 __ pushq(left);
500 __ pushq(right); 444 __ pushq(right);
501 EmitEqualityAsPolymorphicCall(compiler, ic_data, locs, branch, kind, 445 EmitEqualityAsPolymorphicCall(compiler, ic_data, locs, branch, kind,
502 deopt_id, token_pos, try_index); 446 deopt_id, token_pos, try_index);
503 __ Bind(&done); 447 __ Bind(&done);
504 } 448 }
505 449
506 450
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
546 static void EmitSmiComparisonOp(FlowGraphCompiler* compiler, 451 static void EmitSmiComparisonOp(FlowGraphCompiler* compiler,
547 const LocationSummary& locs, 452 const LocationSummary& locs,
548 Token::Kind kind, 453 Token::Kind kind,
549 BranchInstr* branch, 454 BranchInstr* branch,
550 intptr_t deopt_id, 455 intptr_t deopt_id,
551 intptr_t token_pos, 456 intptr_t token_pos,
552 intptr_t try_index) { 457 intptr_t try_index) {
553 Register left = locs.in(0).reg(); 458 Register left = locs.in(0).reg();
554 Register right = locs.in(1).reg(); 459 Register right = locs.in(1).reg();
555 Register temp = locs.temp(0).reg(); 460 Register temp = locs.temp(0).reg();
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
621 if (branch != NULL) { 526 if (branch != NULL) {
622 compiler->EmitDoubleCompareBranch( 527 compiler->EmitDoubleCompareBranch(
623 true_condition, XMM0, XMM1, branch); 528 true_condition, XMM0, XMM1, branch);
624 } else { 529 } else {
625 compiler->EmitDoubleCompareBool( 530 compiler->EmitDoubleCompareBool(
626 true_condition, XMM0, XMM1, locs.out().reg()); 531 true_condition, XMM0, XMM1, locs.out().reg());
627 } 532 }
628 } 533 }
629 534
630 535
536 void EqualityCompareComp::EmitNativeCode(FlowGraphCompiler* compiler) {
537 if (receiver_class_id() == kSmi) {
538 EmitSmiComparisonOp(compiler, *locs(), kind(), NULL, // No branch.
539 deopt_id(), token_pos(), try_index());
540 return;
541 }
542 if (receiver_class_id() == kDouble) {
543 EmitDoubleComparisonOp(compiler, *locs(), kind(), NULL, // No branch.
544 deopt_id(), token_pos(), try_index());
545 return;
546 }
547 if (HasICData() && (ic_data()->NumberOfChecks() > 0)) {
548 EmitGenericEqualityCompare(compiler, *locs(), kind(), NULL, *ic_data(),
549 deopt_id(), token_pos(), try_index());
550 } else {
551 Register left = locs()->in(0).reg();
552 Register right = locs()->in(1).reg();
553 __ pushq(left);
554 __ pushq(right);
555 EmitEqualityAsInstanceCall(compiler, this);
556 }
557 }
558
559
560 LocationSummary* RelationalOpComp::MakeLocationSummary() const {
561 if (operands_class_id() == kSmi || operands_class_id() == kDouble) {
562 const intptr_t kNumInputs = 2;
563 const intptr_t kNumTemps = 1;
564 LocationSummary* summary =
565 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
566 summary->set_in(0, Location::RequiresRegister());
567 summary->set_in(1, Location::RequiresRegister());
568 summary->set_out(Location::RequiresRegister());
569 summary->set_temp(0, Location::RequiresRegister());
570 return summary;
571 }
572 ASSERT(operands_class_id() == kObject);
573 return MakeCallSummary();
574 }
575
576
631 void RelationalOpComp::EmitNativeCode(FlowGraphCompiler* compiler) { 577 void RelationalOpComp::EmitNativeCode(FlowGraphCompiler* compiler) {
632 if (operands_class_id() == kSmi) { 578 if (operands_class_id() == kSmi) {
633 EmitSmiComparisonOp(compiler, *locs(), kind(), NULL, 579 EmitSmiComparisonOp(compiler, *locs(), kind(), NULL,
634 deopt_id(), token_pos(), try_index()); 580 deopt_id(), token_pos(), try_index());
635 return; 581 return;
636 } 582 }
637 if (operands_class_id() == kDouble) { 583 if (operands_class_id() == kDouble) {
638 EmitDoubleComparisonOp(compiler, *locs(), kind(), NULL, 584 EmitDoubleComparisonOp(compiler, *locs(), kind(), NULL,
639 deopt_id(), token_pos(), try_index()); 585 deopt_id(), token_pos(), try_index());
640 return; 586 return;
(...skipping 1489 matching lines...) Expand 10 before | Expand all | Expand 10 after
2130 ASSERT(locs()->out().reg() == RAX); 2076 ASSERT(locs()->out().reg() == RAX);
2131 __ CompareObject(locs()->out().reg(), compiler->bool_true()); 2077 __ CompareObject(locs()->out().reg(), compiler->bool_true());
2132 EmitBranchOnCondition(compiler, branch_condition); 2078 EmitBranchOnCondition(compiler, branch_condition);
2133 } 2079 }
2134 2080
2135 } // namespace dart 2081 } // namespace dart
2136 2082
2137 #undef __ 2083 #undef __
2138 2084
2139 #endif // defined TARGET_ARCH_X64 2085 #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