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

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

Issue 524059: Speed up compares with characters ie single-character strings.... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 10 years, 11 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/runtime.cc ('k') | src/x64/ic-x64.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 2009 the V8 project authors. All rights reserved. 1 // Copyright 2009 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 6246 matching lines...) Expand 10 before | Expand all | Expand 10 after
6257 Label slow; // Fallthrough label. 6257 Label slow; // Fallthrough label.
6258 // Equality is almost reflexive (everything but NaN), so start by testing 6258 // Equality is almost reflexive (everything but NaN), so start by testing
6259 // for "identity and not NaN". 6259 // for "identity and not NaN".
6260 { 6260 {
6261 Label not_identical; 6261 Label not_identical;
6262 __ cmpq(rax, rdx); 6262 __ cmpq(rax, rdx);
6263 __ j(not_equal, &not_identical); 6263 __ j(not_equal, &not_identical);
6264 // Test for NaN. Sadly, we can't just compare to Factory::nan_value(), 6264 // Test for NaN. Sadly, we can't just compare to Factory::nan_value(),
6265 // so we do the second best thing - test it ourselves. 6265 // so we do the second best thing - test it ourselves.
6266 6266
6267 Label return_equal; 6267 if (never_nan_nan_) {
6268 Label heap_number; 6268 __ xor_(rax, rax);
6269 // If it's not a heap number, then return equal. 6269 __ ret(0);
6270 __ Cmp(FieldOperand(rdx, HeapObject::kMapOffset), 6270 } else {
6271 Factory::heap_number_map()); 6271 Label return_equal;
6272 __ j(equal, &heap_number); 6272 Label heap_number;
6273 __ bind(&return_equal); 6273 // If it's not a heap number, then return equal.
6274 __ xor_(rax, rax); 6274 __ Cmp(FieldOperand(rdx, HeapObject::kMapOffset),
6275 __ ret(0); 6275 Factory::heap_number_map());
6276 __ j(equal, &heap_number);
6277 __ bind(&return_equal);
6278 __ xor_(rax, rax);
6279 __ ret(0);
6276 6280
6277 __ bind(&heap_number); 6281 __ bind(&heap_number);
6278 // It is a heap number, so return non-equal if it's NaN and equal if it's 6282 // It is a heap number, so return non-equal if it's NaN and equal if
6279 // not NaN. 6283 // it's not NaN.
6280 // The representation of NaN values has all exponent bits (52..62) set, 6284 // The representation of NaN values has all exponent bits (52..62) set,
6281 // and not all mantissa bits (0..51) clear. 6285 // and not all mantissa bits (0..51) clear.
6282 // We only allow QNaNs, which have bit 51 set (which also rules out 6286 // We only allow QNaNs, which have bit 51 set (which also rules out
6283 // the value being Infinity). 6287 // the value being Infinity).
6284 6288
6285 // Value is a QNaN if value & kQuietNaNMask == kQuietNaNMask, i.e., 6289 // Value is a QNaN if value & kQuietNaNMask == kQuietNaNMask, i.e.,
6286 // all bits in the mask are set. We only need to check the word 6290 // all bits in the mask are set. We only need to check the word
6287 // that contains the exponent and high bit of the mantissa. 6291 // that contains the exponent and high bit of the mantissa.
6288 ASSERT_NE(0, (kQuietNaNHighBitsMask << 1) & 0x80000000u); 6292 ASSERT_NE(0, (kQuietNaNHighBitsMask << 1) & 0x80000000u);
6289 __ movl(rdx, FieldOperand(rdx, HeapNumber::kExponentOffset)); 6293 __ movl(rdx, FieldOperand(rdx, HeapNumber::kExponentOffset));
6290 __ xorl(rax, rax); 6294 __ xorl(rax, rax);
6291 __ addl(rdx, rdx); // Shift value and mask so mask applies to top bits. 6295 __ addl(rdx, rdx); // Shift value and mask so mask applies to top bits.
6292 __ cmpl(rdx, Immediate(kQuietNaNHighBitsMask << 1)); 6296 __ cmpl(rdx, Immediate(kQuietNaNHighBitsMask << 1));
6293 __ setcc(above_equal, rax); 6297 __ setcc(above_equal, rax);
6294 __ ret(0); 6298 __ ret(0);
6299 }
6295 6300
6296 __ bind(&not_identical); 6301 __ bind(&not_identical);
6297 } 6302 }
6298 6303
6299 // If we're doing a strict equality comparison, we don't have to do 6304 // If we're doing a strict equality comparison, we don't have to do
6300 // type conversion, so we generate code to do fast comparison for objects 6305 // type conversion, so we generate code to do fast comparison for objects
6301 // and oddballs. Non-smi numbers and strings still go through the usual 6306 // and oddballs. Non-smi numbers and strings still go through the usual
6302 // slow-case code. 6307 // slow-case code.
6303 if (strict_) { 6308 if (strict_) {
6304 // If either is a Smi (we know that not both are), then they can only 6309 // If either is a Smi (we know that not both are), then they can only
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after
6431 6436
6432 6437
6433 void CompareStub::BranchIfNonSymbol(MacroAssembler* masm, 6438 void CompareStub::BranchIfNonSymbol(MacroAssembler* masm,
6434 Label* label, 6439 Label* label,
6435 Register object, 6440 Register object,
6436 Register scratch) { 6441 Register scratch) {
6437 __ JumpIfSmi(object, label); 6442 __ JumpIfSmi(object, label);
6438 __ movq(scratch, FieldOperand(object, HeapObject::kMapOffset)); 6443 __ movq(scratch, FieldOperand(object, HeapObject::kMapOffset));
6439 __ movzxbq(scratch, 6444 __ movzxbq(scratch,
6440 FieldOperand(scratch, Map::kInstanceTypeOffset)); 6445 FieldOperand(scratch, Map::kInstanceTypeOffset));
6441 __ and_(scratch, Immediate(kIsSymbolMask | kIsNotStringMask)); 6446 // Ensure that no non-strings have the symbol bit set.
6442 __ cmpb(scratch, Immediate(kSymbolTag | kStringTag)); 6447 ASSERT(kNotStringTag + kIsSymbolMask > LAST_TYPE);
6443 __ j(not_equal, label); 6448 ASSERT(kSymbolTag != 0);
6449 __ test(scratch, Immediate(kIsSymbolMask));
6450 __ j(zero, label);
6444 } 6451 }
6445 6452
6446 6453
6447 // Call the function just below TOS on the stack with the given 6454 // Call the function just below TOS on the stack with the given
6448 // arguments. The receiver is the TOS. 6455 // arguments. The receiver is the TOS.
6449 void CodeGenerator::CallWithArguments(ZoneList<Expression*>* args, 6456 void CodeGenerator::CallWithArguments(ZoneList<Expression*>* args,
6450 int position) { 6457 int position) {
6451 // Push the arguments ("left-to-right") on the stack. 6458 // Push the arguments ("left-to-right") on the stack.
6452 int arg_count = args->length(); 6459 int arg_count = args->length();
6453 for (int i = 0; i < arg_count; i++) { 6460 for (int i = 0; i < arg_count; i++) {
(...skipping 1279 matching lines...) Expand 10 before | Expand all | Expand 10 after
7733 // returning. 7740 // returning.
7734 if (!HasArgumentsInRegisters()) { 7741 if (!HasArgumentsInRegisters()) {
7735 __ ret(2 * kPointerSize); // Remove both operands 7742 __ ret(2 * kPointerSize); // Remove both operands
7736 } else { 7743 } else {
7737 __ ret(0); 7744 __ ret(0);
7738 } 7745 }
7739 } 7746 }
7740 7747
7741 7748
7742 int CompareStub::MinorKey() { 7749 int CompareStub::MinorKey() {
7743 // Encode the two parameters in a unique 16 bit value. 7750 // Encode the three parameters in a unique 16 bit value.
7744 ASSERT(static_cast<unsigned>(cc_) < (1 << 15)); 7751 ASSERT(static_cast<unsigned>(cc_) < (1 << 14));
7745 return (static_cast<unsigned>(cc_) << 1) | (strict_ ? 1 : 0); 7752 int nnn_value = (never_nan_nan_ ? 2 : 0);
7753 if (cc_ != equal) nnn_value = 0; // Avoid duplicate stubs.
7754 return (static_cast<unsigned>(cc_) << 2) | nnn_value | (strict_ ? 1 : 0);
7755 }
7756
7757
7758 const char* CompareStub::GetName() {
7759 switch(cc_) {
7760 case less: return "CompareStub_LT";
7761 case greater: return "CompareStub_GT";
7762 case less_equal: return "CompareStub_LE";
7763 case greater_equal: return "CompareStub_GE";
7764 case not_equal: {
7765 if (strict_) {
7766 if (never_nan_nan_) {
7767 return "CompareStub_NE_STRICT_NO_NAN";
7768 } else {
7769 return "CompareStub_NE_STRICT";
7770 }
7771 } else {
7772 if (never_nan_nan_) {
7773 return "CompareStub_NE_NO_NAN";
7774 } else {
7775 return "CompareStub_NE";
7776 }
7777 }
7778 }
7779 case equal: {
7780 if (strict_) {
7781 if (never_nan_nan_) {
7782 return "CompareStub_EQ_STRICT_NO_NAN";
7783 } else {
7784 return "CompareStub_EQ_STRICT";
7785 }
7786 } else {
7787 if (never_nan_nan_) {
7788 return "CompareStub_EQ_NO_NAN";
7789 } else {
7790 return "CompareStub_EQ";
7791 }
7792 }
7793 }
7794 default: return "CompareStub";
7795 }
7746 } 7796 }
7747 7797
7748 7798
7749 void StringAddStub::Generate(MacroAssembler* masm) { 7799 void StringAddStub::Generate(MacroAssembler* masm) {
7750 Label string_add_runtime; 7800 Label string_add_runtime;
7751 7801
7752 // Load the two arguments. 7802 // Load the two arguments.
7753 __ movq(rax, Operand(rsp, 2 * kPointerSize)); // First argument. 7803 __ movq(rax, Operand(rsp, 2 * kPointerSize)); // First argument.
7754 __ movq(rdx, Operand(rsp, 1 * kPointerSize)); // Second argument. 7804 __ movq(rdx, Operand(rsp, 1 * kPointerSize)); // Second argument.
7755 7805
(...skipping 306 matching lines...) Expand 10 before | Expand all | Expand 10 after
8062 masm.GetCode(&desc); 8112 masm.GetCode(&desc);
8063 // Call the function from C++. 8113 // Call the function from C++.
8064 return FUNCTION_CAST<ModuloFunction>(buffer); 8114 return FUNCTION_CAST<ModuloFunction>(buffer);
8065 } 8115 }
8066 8116
8067 #endif 8117 #endif
8068 8118
8069 #undef __ 8119 #undef __
8070 8120
8071 } } // namespace v8::internal 8121 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/runtime.cc ('k') | src/x64/ic-x64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698