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

Side by Side Diff: src/ia32/codegen-ia32.cc

Issue 1040002: Fix bug in the count operation where we statically know the input is a smi. (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: Rearranged comments Created 10 years, 9 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 | « src/data-flow.cc ('k') | test/mjsunit/compiler/loopcount.js » ('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 2010 the V8 project authors. All rights reserved. 1 // Copyright 2010 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 6666 matching lines...) Expand 10 before | Expand all | Expand 10 after
6677 Result old_value; // Only allocated in the postfix case. 6677 Result old_value; // Only allocated in the postfix case.
6678 if (is_postfix) { 6678 if (is_postfix) {
6679 // Allocate a temporary to preserve the old value. 6679 // Allocate a temporary to preserve the old value.
6680 old_value = allocator_->Allocate(); 6680 old_value = allocator_->Allocate();
6681 ASSERT(old_value.is_valid()); 6681 ASSERT(old_value.is_valid());
6682 __ mov(old_value.reg(), new_value.reg()); 6682 __ mov(old_value.reg(), new_value.reg());
6683 } 6683 }
6684 // Ensure the new value is writable. 6684 // Ensure the new value is writable.
6685 frame_->Spill(new_value.reg()); 6685 frame_->Spill(new_value.reg());
6686 6686
6687 // In order to combine the overflow and the smi tag check, we need 6687 Result tmp;
6688 // to be able to allocate a byte register. We attempt to do so 6688 if (new_value.is_smi()) {
6689 // without spilling. If we fail, we will generate separate overflow 6689 if (FLAG_debug_code) {
6690 // and smi tag checks. 6690 __ AbortIfNotSmi(new_value.reg(), "Operand not a smi");
6691 // 6691 }
6692 // We allocate and clear the temporary byte register before 6692 } else {
6693 // performing the count operation since clearing the register using 6693 // We don't know statically if the input is a smi.
6694 // xor will clear the overflow flag. 6694 // In order to combine the overflow and the smi tag check, we need
6695 Result tmp = allocator_->AllocateByteRegisterWithoutSpilling(); 6695 // to be able to allocate a byte register. We attempt to do so
6696 if (tmp.is_valid()) { 6696 // without spilling. If we fail, we will generate separate overflow
6697 __ Set(tmp.reg(), Immediate(0)); 6697 // and smi tag checks.
6698 // We allocate and clear a temporary byte register before performing
6699 // the count operation since clearing the register using xor will clear
6700 // the overflow flag.
6701 tmp = allocator_->AllocateByteRegisterWithoutSpilling();
6702 if (tmp.is_valid()) {
6703 __ Set(tmp.reg(), Immediate(0));
6704 }
6698 } 6705 }
6699 6706
6700
6701 if (is_increment) { 6707 if (is_increment) {
6702 __ add(Operand(new_value.reg()), Immediate(Smi::FromInt(1))); 6708 __ add(Operand(new_value.reg()), Immediate(Smi::FromInt(1)));
6703 } else { 6709 } else {
6704 __ sub(Operand(new_value.reg()), Immediate(Smi::FromInt(1))); 6710 __ sub(Operand(new_value.reg()), Immediate(Smi::FromInt(1)));
6705 } 6711 }
6706 6712
6713 DeferredCode* deferred = NULL;
6714 if (is_postfix) {
6715 deferred = new DeferredPostfixCountOperation(new_value.reg(),
6716 old_value.reg(),
6717 is_increment);
6718 } else {
6719 deferred = new DeferredPrefixCountOperation(new_value.reg(),
6720 is_increment);
6721 }
6722
6707 if (new_value.is_smi()) { 6723 if (new_value.is_smi()) {
6708 if (FLAG_debug_code) { 6724 // In case we have a smi as input just check for overflow.
6709 __ AbortIfNotSmi(new_value.reg(), "Argument not a smi"); 6725 deferred->Branch(overflow);
6710 }
6711 if (tmp.is_valid()) tmp.Unuse();
6712 } else { 6726 } else {
6713 DeferredCode* deferred = NULL;
6714 if (is_postfix) {
6715 deferred = new DeferredPostfixCountOperation(new_value.reg(),
6716 old_value.reg(),
6717 is_increment);
6718 } else {
6719 deferred = new DeferredPrefixCountOperation(new_value.reg(),
6720 is_increment);
6721 }
6722
6723 // If the count operation didn't overflow and the result is a valid 6727 // If the count operation didn't overflow and the result is a valid
6724 // smi, we're done. Otherwise, we jump to the deferred slow-case 6728 // smi, we're done. Otherwise, we jump to the deferred slow-case
6725 // code. 6729 // code.
6730 // We combine the overflow and the smi tag check if we could
6731 // successfully allocate a temporary byte register.
6726 if (tmp.is_valid()) { 6732 if (tmp.is_valid()) {
6727 // We combine the overflow and the smi tag check if we could
6728 // successfully allocate a temporary byte register.
6729 __ setcc(overflow, tmp.reg()); 6733 __ setcc(overflow, tmp.reg());
6730 __ or_(Operand(tmp.reg()), new_value.reg()); 6734 __ or_(Operand(tmp.reg()), new_value.reg());
6731 __ test(tmp.reg(), Immediate(kSmiTagMask)); 6735 __ test(tmp.reg(), Immediate(kSmiTagMask));
6732 tmp.Unuse(); 6736 tmp.Unuse();
6733 deferred->Branch(not_zero); 6737 deferred->Branch(not_zero);
6734 } else { 6738 } else {
6735 // Otherwise we test separately for overflow and smi tag. 6739 // Otherwise we test separately for overflow and smi tag.
6736 deferred->Branch(overflow); 6740 deferred->Branch(overflow);
6737 __ test(new_value.reg(), Immediate(kSmiTagMask)); 6741 __ test(new_value.reg(), Immediate(kSmiTagMask));
6738 deferred->Branch(not_zero); 6742 deferred->Branch(not_zero);
6739 } 6743 }
6740 deferred->BindExit();
6741 } 6744 }
6745 deferred->BindExit();
6746
6742 6747
6743 // Postfix: store the old value in the allocated slot under the 6748 // Postfix: store the old value in the allocated slot under the
6744 // reference. 6749 // reference.
6745 if (is_postfix) frame_->SetElementAt(target.size(), &old_value); 6750 if (is_postfix) frame_->SetElementAt(target.size(), &old_value);
6746 6751
6747 frame_->Push(&new_value); 6752 frame_->Push(&new_value);
6748 // Non-constant: update the reference. 6753 // Non-constant: update the reference.
6749 if (!is_const) target.SetValue(NOT_CONST_INIT); 6754 if (!is_const) target.SetValue(NOT_CONST_INIT);
6750 } 6755 }
6751 6756
(...skipping 5108 matching lines...) Expand 10 before | Expand all | Expand 10 after
11860 11865
11861 // Call the runtime; it returns -1 (less), 0 (equal), or 1 (greater) 11866 // Call the runtime; it returns -1 (less), 0 (equal), or 1 (greater)
11862 // tagged as a small integer. 11867 // tagged as a small integer.
11863 __ bind(&runtime); 11868 __ bind(&runtime);
11864 __ TailCallRuntime(Runtime::kStringCompare, 2, 1); 11869 __ TailCallRuntime(Runtime::kStringCompare, 2, 1);
11865 } 11870 }
11866 11871
11867 #undef __ 11872 #undef __
11868 11873
11869 } } // namespace v8::internal 11874 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/data-flow.cc ('k') | test/mjsunit/compiler/loopcount.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698