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

Side by Side Diff: runtime/vm/intermediate_language_arm.cc

Issue 24203004: Dart VM: Simplify code generation for equality operators. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: rebased Created 7 years, 2 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 | « runtime/vm/debugger.cc ('k') | runtime/vm/intermediate_language_ia32.cc » ('j') | 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) 2013, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2013, 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_ARM. 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_ARM.
6 #if defined(TARGET_ARCH_ARM) 6 #if defined(TARGET_ARCH_ARM)
7 7
8 #include "vm/intermediate_language.h" 8 #include "vm/intermediate_language.h"
9 9
10 #include "vm/dart_entry.h" 10 #include "vm/dart_entry.h"
(...skipping 343 matching lines...) Expand 10 before | Expand all | Expand 10 after
354 const ICData& original_ic_data) { 354 const ICData& original_ic_data) {
355 if (!compiler->is_optimizing()) { 355 if (!compiler->is_optimizing()) {
356 compiler->AddCurrentDescriptor(PcDescriptors::kDeopt, 356 compiler->AddCurrentDescriptor(PcDescriptors::kDeopt,
357 deopt_id, 357 deopt_id,
358 token_pos); 358 token_pos);
359 } 359 }
360 const int kNumberOfArguments = 2; 360 const int kNumberOfArguments = 2;
361 const Array& kNoArgumentNames = Object::null_array(); 361 const Array& kNoArgumentNames = Object::null_array();
362 const int kNumArgumentsChecked = 2; 362 const int kNumArgumentsChecked = 2;
363 363
364 Label check_identity;
365 __ LoadImmediate(IP, reinterpret_cast<intptr_t>(Object::null()));
366 __ ldm(IA, SP, (1 << R0) | (1 << R1));
367 __ cmp(R1, ShifterOperand(IP));
368 __ b(&check_identity, EQ);
369 __ cmp(R0, ShifterOperand(IP));
370 __ b(&check_identity, EQ);
371
372 ICData& equality_ic_data = ICData::ZoneHandle(); 364 ICData& equality_ic_data = ICData::ZoneHandle();
373 if (compiler->is_optimizing() && FLAG_propagate_ic_data) { 365 if (compiler->is_optimizing() && FLAG_propagate_ic_data) {
374 ASSERT(!original_ic_data.IsNull()); 366 ASSERT(!original_ic_data.IsNull());
375 if (original_ic_data.NumberOfChecks() == 0) { 367 if (original_ic_data.NumberOfChecks() == 0) {
376 // IC call for reoptimization populates original ICData. 368 // IC call for reoptimization populates original ICData.
377 equality_ic_data = original_ic_data.raw(); 369 equality_ic_data = original_ic_data.raw();
378 } else { 370 } else {
379 // Megamorphic call. 371 // Megamorphic call.
380 equality_ic_data = original_ic_data.AsUnaryClassChecks(); 372 equality_ic_data = original_ic_data.AsUnaryClassChecks();
381 } 373 }
382 } else { 374 } else {
383 const Array& arguments_descriptor = 375 const Array& arguments_descriptor =
384 Array::Handle(ArgumentsDescriptor::New(kNumberOfArguments, 376 Array::Handle(ArgumentsDescriptor::New(kNumberOfArguments,
385 kNoArgumentNames)); 377 kNoArgumentNames));
386 equality_ic_data = ICData::New(compiler->parsed_function().function(), 378 equality_ic_data = ICData::New(compiler->parsed_function().function(),
387 Symbols::EqualOperator(), 379 Symbols::EqualOperator(),
388 arguments_descriptor, 380 arguments_descriptor,
389 deopt_id, 381 deopt_id,
390 kNumArgumentsChecked); 382 kNumArgumentsChecked);
391 } 383 }
392 compiler->GenerateInstanceCall(deopt_id, 384 compiler->GenerateInstanceCall(deopt_id,
393 token_pos, 385 token_pos,
394 kNumberOfArguments, 386 kNumberOfArguments,
395 kNoArgumentNames, 387 kNoArgumentNames,
396 locs, 388 locs,
397 equality_ic_data); 389 equality_ic_data);
398 Label check_ne;
399 __ b(&check_ne);
400
401 __ Bind(&check_identity);
402 Label equality_done;
403 if (compiler->is_optimizing()) {
404 // No need to update IC data.
405 __ PopList((1 << R0) | (1 << R1));
406 __ cmp(R0, ShifterOperand(R1));
407 __ LoadObject(R0, Bool::Get(kind != Token::kEQ), NE);
408 __ LoadObject(R0, Bool::Get(kind == Token::kEQ), EQ);
409 if (kind == Token::kNE) {
410 // Skip not-equal result conversion.
411 __ b(&equality_done);
412 }
413 } else {
414 // Call stub, load IC data in register. The stub will update ICData if
415 // necessary.
416 Register ic_data_reg = locs->temp(0).reg();
417 ASSERT(ic_data_reg == R5); // Stub depends on it.
418 __ LoadObject(ic_data_reg, equality_ic_data);
419 // Pass left in R1 and right in R0.
420 compiler->GenerateCall(token_pos,
421 &StubCode::EqualityWithNullArgLabel(),
422 PcDescriptors::kRuntimeCall,
423 locs);
424 __ Drop(2);
425 }
426 __ Bind(&check_ne);
427 if (kind == Token::kNE) { 390 if (kind == Token::kNE) {
428 // Negate the condition: true label returns false and vice versa. 391 // Negate the condition: true label returns false and vice versa.
429 __ CompareObject(R0, Bool::True()); 392 __ CompareObject(R0, Bool::True());
430 __ LoadObject(R0, Bool::True(), NE); 393 __ LoadObject(R0, Bool::True(), NE);
431 __ LoadObject(R0, Bool::False(), EQ); 394 __ LoadObject(R0, Bool::False(), EQ);
432 } 395 }
433 __ Bind(&equality_done);
434 } 396 }
435 397
436 398
437 static void LoadValueCid(FlowGraphCompiler* compiler, 399 static void LoadValueCid(FlowGraphCompiler* compiler,
438 Register value_cid_reg, 400 Register value_cid_reg,
439 Register value_reg, 401 Register value_reg,
440 Label* value_is_smi = NULL) { 402 Label* value_is_smi = NULL) {
441 Label done; 403 Label done;
442 if (value_is_smi == NULL) { 404 if (value_is_smi == NULL) {
443 __ mov(value_cid_reg, ShifterOperand(kSmiCid)); 405 __ mov(value_cid_reg, ShifterOperand(kSmiCid));
(...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after
605 LocationSummary* locs, 567 LocationSummary* locs,
606 Token::Kind kind, 568 Token::Kind kind,
607 BranchInstr* branch, 569 BranchInstr* branch,
608 const ICData& ic_data, 570 const ICData& ic_data,
609 intptr_t deopt_id, 571 intptr_t deopt_id,
610 intptr_t token_pos) { 572 intptr_t token_pos) {
611 ASSERT((kind == Token::kEQ) || (kind == Token::kNE)); 573 ASSERT((kind == Token::kEQ) || (kind == Token::kNE));
612 ASSERT(!ic_data.IsNull() && (ic_data.NumberOfChecks() > 0)); 574 ASSERT(!ic_data.IsNull() && (ic_data.NumberOfChecks() > 0));
613 Register left = locs->in(0).reg(); 575 Register left = locs->in(0).reg();
614 Register right = locs->in(1).reg(); 576 Register right = locs->in(1).reg();
615 Label done, identity_compare, non_null_compare;
616 __ LoadImmediate(IP, reinterpret_cast<intptr_t>(Object::null()));
617 __ cmp(right, ShifterOperand(IP));
618 __ b(&identity_compare, EQ);
619 __ cmp(left, ShifterOperand(IP));
620 __ b(&non_null_compare, NE);
621 // Comparison with NULL is "===".
622 __ Bind(&identity_compare);
623 __ cmp(left, ShifterOperand(right));
624 Condition cond = TokenKindToSmiCondition(kind);
625 if (branch != NULL) {
626 branch->EmitBranchOnCondition(compiler, cond);
627 } else {
628 Register result = locs->out().reg();
629 Label load_true;
630 __ b(&load_true, cond);
631 __ LoadObject(result, Bool::False());
632 __ b(&done);
633 __ Bind(&load_true);
634 __ LoadObject(result, Bool::True());
635 }
636 __ b(&done);
637 __ Bind(&non_null_compare); // Receiver is not null.
638 ASSERT(left == R1); 577 ASSERT(left == R1);
639 ASSERT(right == R0); 578 ASSERT(right == R0);
640 __ PushList((1 << R0) | (1 << R1)); 579 __ PushList((1 << R0) | (1 << R1));
641 EmitEqualityAsPolymorphicCall(compiler, ic_data, locs, branch, kind, 580 EmitEqualityAsPolymorphicCall(compiler, ic_data, locs, branch, kind,
642 deopt_id, token_pos); 581 deopt_id, token_pos);
643 __ Bind(&done);
644 } 582 }
645 583
646 584
647 static Condition FlipCondition(Condition condition) { 585 static Condition FlipCondition(Condition condition) {
648 switch (condition) { 586 switch (condition) {
649 case EQ: return EQ; 587 case EQ: return EQ;
650 case NE: return NE; 588 case NE: return NE;
651 case LT: return GT; 589 case LT: return GT;
652 case LE: return GE; 590 case LE: return GE;
653 case GT: return LT; 591 case GT: return LT;
(...skipping 4024 matching lines...) Expand 10 before | Expand all | Expand 10 after
4678 compiler->GenerateCall(token_pos(), 4616 compiler->GenerateCall(token_pos(),
4679 &label, 4617 &label,
4680 PcDescriptors::kOther, 4618 PcDescriptors::kOther,
4681 locs()); 4619 locs());
4682 __ Drop(2); // Discard type arguments and receiver. 4620 __ Drop(2); // Discard type arguments and receiver.
4683 } 4621 }
4684 4622
4685 } // namespace dart 4623 } // namespace dart
4686 4624
4687 #endif // defined TARGET_ARCH_ARM 4625 #endif // defined TARGET_ARCH_ARM
OLDNEW
« no previous file with comments | « runtime/vm/debugger.cc ('k') | runtime/vm/intermediate_language_ia32.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698