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

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

Issue 3016004: Delay the pushing of arguments until just before calling runtime in CompareSt... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 10 years, 5 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 | « no previous file | src/x64/codegen-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 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 11821 matching lines...) Expand 10 before | Expand all | Expand 10 after
11832 __ j(above_equal, &return_not_equal); 11832 __ j(above_equal, &return_not_equal);
11833 11833
11834 // Check for oddballs: true, false, null, undefined. 11834 // Check for oddballs: true, false, null, undefined.
11835 __ CmpInstanceType(ecx, ODDBALL_TYPE); 11835 __ CmpInstanceType(ecx, ODDBALL_TYPE);
11836 __ j(equal, &return_not_equal); 11836 __ j(equal, &return_not_equal);
11837 11837
11838 // Fall through to the general case. 11838 // Fall through to the general case.
11839 __ bind(&slow); 11839 __ bind(&slow);
11840 } 11840 }
11841 11841
11842 // Push arguments below the return address.
11843 __ pop(ecx);
11844 __ push(eax);
11845 __ push(edx);
11846 __ push(ecx);
11847
11848 // Generate the number comparison code. 11842 // Generate the number comparison code.
11849 if (include_number_compare_) { 11843 if (include_number_compare_) {
11850 Label non_number_comparison; 11844 Label non_number_comparison;
11851 Label unordered; 11845 Label unordered;
11852 if (CpuFeatures::IsSupported(SSE2)) { 11846 if (CpuFeatures::IsSupported(SSE2)) {
11853 CpuFeatures::Scope use_sse2(SSE2); 11847 CpuFeatures::Scope use_sse2(SSE2);
11854 CpuFeatures::Scope use_cmov(CMOV); 11848 CpuFeatures::Scope use_cmov(CMOV);
11855 11849
11856 FloatingPointHelper::LoadSSE2Operands(masm, &non_number_comparison); 11850 FloatingPointHelper::LoadSSE2Operands(masm, &non_number_comparison);
11857 __ ucomisd(xmm0, xmm1); 11851 __ ucomisd(xmm0, xmm1);
11858 11852
11859 // Don't base result on EFLAGS when a NaN is involved. 11853 // Don't base result on EFLAGS when a NaN is involved.
11860 __ j(parity_even, &unordered, not_taken); 11854 __ j(parity_even, &unordered, not_taken);
11861 // Return a result of -1, 0, or 1, based on EFLAGS. 11855 // Return a result of -1, 0, or 1, based on EFLAGS.
11862 __ mov(eax, 0); // equal 11856 __ mov(eax, 0); // equal
11863 __ mov(ecx, Immediate(Smi::FromInt(1))); 11857 __ mov(ecx, Immediate(Smi::FromInt(1)));
11864 __ cmov(above, eax, Operand(ecx)); 11858 __ cmov(above, eax, Operand(ecx));
11865 __ mov(ecx, Immediate(Smi::FromInt(-1))); 11859 __ mov(ecx, Immediate(Smi::FromInt(-1)));
11866 __ cmov(below, eax, Operand(ecx)); 11860 __ cmov(below, eax, Operand(ecx));
11867 __ ret(2 * kPointerSize); 11861 __ ret(0);
11868 } else { 11862 } else {
11869 FloatingPointHelper::CheckFloatOperands( 11863 FloatingPointHelper::CheckFloatOperands(
11870 masm, &non_number_comparison, ebx); 11864 masm, &non_number_comparison, ebx);
11871 FloatingPointHelper::LoadFloatOperands(masm, ecx); 11865 FloatingPointHelper::LoadFloatOperands(masm, ecx);
11872 __ FCmp(); 11866 __ FCmp();
11873 11867
11874 // Don't base result on EFLAGS when a NaN is involved. 11868 // Don't base result on EFLAGS when a NaN is involved.
11875 __ j(parity_even, &unordered, not_taken); 11869 __ j(parity_even, &unordered, not_taken);
11876 11870
11877 Label below_label, above_label; 11871 Label below_label, above_label;
11878 // Return a result of -1, 0, or 1, based on EFLAGS. In all cases remove 11872 // Return a result of -1, 0, or 1, based on EFLAGS.
11879 // two arguments from the stack as they have been pushed in preparation
11880 // of a possible runtime call.
11881 __ j(below, &below_label, not_taken); 11873 __ j(below, &below_label, not_taken);
11882 __ j(above, &above_label, not_taken); 11874 __ j(above, &above_label, not_taken);
11883 11875
11884 __ xor_(eax, Operand(eax)); 11876 __ xor_(eax, Operand(eax));
11885 __ ret(2 * kPointerSize); 11877 __ ret(0);
11886 11878
11887 __ bind(&below_label); 11879 __ bind(&below_label);
11888 __ mov(eax, Immediate(Smi::FromInt(-1))); 11880 __ mov(eax, Immediate(Smi::FromInt(-1)));
11889 __ ret(2 * kPointerSize); 11881 __ ret(0);
11890 11882
11891 __ bind(&above_label); 11883 __ bind(&above_label);
11892 __ mov(eax, Immediate(Smi::FromInt(1))); 11884 __ mov(eax, Immediate(Smi::FromInt(1)));
11893 __ ret(2 * kPointerSize); 11885 __ ret(0);
11894 } 11886 }
11895 11887
11896 // If one of the numbers was NaN, then the result is always false. 11888 // If one of the numbers was NaN, then the result is always false.
11897 // The cc is never not-equal. 11889 // The cc is never not-equal.
11898 __ bind(&unordered); 11890 __ bind(&unordered);
11899 ASSERT(cc_ != not_equal); 11891 ASSERT(cc_ != not_equal);
11900 if (cc_ == less || cc_ == less_equal) { 11892 if (cc_ == less || cc_ == less_equal) {
11901 __ mov(eax, Immediate(Smi::FromInt(1))); 11893 __ mov(eax, Immediate(Smi::FromInt(1)));
11902 } else { 11894 } else {
11903 __ mov(eax, Immediate(Smi::FromInt(-1))); 11895 __ mov(eax, Immediate(Smi::FromInt(-1)));
11904 } 11896 }
11905 __ ret(2 * kPointerSize); // eax, edx were pushed 11897 __ ret(0);
11906 11898
11907 // The number comparison code did not provide a valid result. 11899 // The number comparison code did not provide a valid result.
11908 __ bind(&non_number_comparison); 11900 __ bind(&non_number_comparison);
11909 } 11901 }
11910 11902
11911 // Fast negative check for symbol-to-symbol equality. 11903 // Fast negative check for symbol-to-symbol equality.
11912 Label check_for_strings; 11904 Label check_for_strings;
11913 if (cc_ == equal) { 11905 if (cc_ == equal) {
11914 BranchIfNonSymbol(masm, &check_for_strings, eax, ecx); 11906 BranchIfNonSymbol(masm, &check_for_strings, eax, ecx);
11915 BranchIfNonSymbol(masm, &check_for_strings, edx, ecx); 11907 BranchIfNonSymbol(masm, &check_for_strings, edx, ecx);
11916 11908
11917 // We've already checked for object identity, so if both operands 11909 // We've already checked for object identity, so if both operands
11918 // are symbols they aren't equal. Register eax already holds a 11910 // are symbols they aren't equal. Register eax already holds a
11919 // non-zero value, which indicates not equal, so just return. 11911 // non-zero value, which indicates not equal, so just return.
11920 __ ret(2 * kPointerSize); 11912 __ ret(0);
11921 } 11913 }
11922 11914
11923 __ bind(&check_for_strings); 11915 __ bind(&check_for_strings);
11924 11916
11925 __ JumpIfNotBothSequentialAsciiStrings(edx, eax, ecx, ebx, 11917 __ JumpIfNotBothSequentialAsciiStrings(edx, eax, ecx, ebx,
11926 &check_unequal_objects); 11918 &check_unequal_objects);
11927 11919
11928 // Inline comparison of ascii strings. 11920 // Inline comparison of ascii strings.
11929 StringCompareStub::GenerateCompareFlatAsciiStrings(masm, 11921 StringCompareStub::GenerateCompareFlatAsciiStrings(masm,
11930 edx, 11922 edx,
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
11963 __ j(zero, &return_unequal); 11955 __ j(zero, &return_unequal);
11964 __ test_b(FieldOperand(ebx, Map::kBitFieldOffset), 11956 __ test_b(FieldOperand(ebx, Map::kBitFieldOffset),
11965 1 << Map::kIsUndetectable); 11957 1 << Map::kIsUndetectable);
11966 __ j(zero, &return_unequal); 11958 __ j(zero, &return_unequal);
11967 // The objects are both undetectable, so they both compare as the value 11959 // The objects are both undetectable, so they both compare as the value
11968 // undefined, and are equal. 11960 // undefined, and are equal.
11969 __ Set(eax, Immediate(EQUAL)); 11961 __ Set(eax, Immediate(EQUAL));
11970 __ bind(&return_unequal); 11962 __ bind(&return_unequal);
11971 // Return non-equal by returning the non-zero object pointer in eax, 11963 // Return non-equal by returning the non-zero object pointer in eax,
11972 // or return equal if we fell through to here. 11964 // or return equal if we fell through to here.
11973 __ ret(2 * kPointerSize); // rax, rdx were pushed 11965 __ ret(0); // rax, rdx were pushed
11974 __ bind(&not_both_objects); 11966 __ bind(&not_both_objects);
11975 } 11967 }
11976 11968
11977 // must swap argument order 11969 // Push arguments below the return address.
11978 __ pop(ecx); 11970 __ pop(ecx);
11979 __ pop(edx);
11980 __ pop(eax);
11981 __ push(edx); 11971 __ push(edx);
11982 __ push(eax); 11972 __ push(eax);
11983 11973
11984 // Figure out which native to call and setup the arguments. 11974 // Figure out which native to call and setup the arguments.
11985 Builtins::JavaScript builtin; 11975 Builtins::JavaScript builtin;
11986 if (cc_ == equal) { 11976 if (cc_ == equal) {
11987 builtin = strict_ ? Builtins::STRICT_EQUALS : Builtins::EQUALS; 11977 builtin = strict_ ? Builtins::STRICT_EQUALS : Builtins::EQUALS;
11988 } else { 11978 } else {
11989 builtin = Builtins::COMPARE; 11979 builtin = Builtins::COMPARE;
11990 __ push(Immediate(Smi::FromInt(NegativeComparisonResult(cc_)))); 11980 __ push(Immediate(Smi::FromInt(NegativeComparisonResult(cc_))));
(...skipping 1556 matching lines...) Expand 10 before | Expand all | Expand 10 after
13547 13537
13548 // Compare lengths - strings up to min-length are equal. 13538 // Compare lengths - strings up to min-length are equal.
13549 __ bind(&compare_lengths); 13539 __ bind(&compare_lengths);
13550 __ test(length_delta, Operand(length_delta)); 13540 __ test(length_delta, Operand(length_delta));
13551 __ j(not_zero, &result_not_equal); 13541 __ j(not_zero, &result_not_equal);
13552 13542
13553 // Result is EQUAL. 13543 // Result is EQUAL.
13554 ASSERT_EQ(0, EQUAL); 13544 ASSERT_EQ(0, EQUAL);
13555 ASSERT_EQ(0, kSmiTag); 13545 ASSERT_EQ(0, kSmiTag);
13556 __ Set(eax, Immediate(Smi::FromInt(EQUAL))); 13546 __ Set(eax, Immediate(Smi::FromInt(EQUAL)));
13557 __ ret(2 * kPointerSize); 13547 __ ret(0);
13558 13548
13559 __ bind(&result_not_equal); 13549 __ bind(&result_not_equal);
13560 __ j(greater, &result_greater); 13550 __ j(greater, &result_greater);
13561 13551
13562 // Result is LESS. 13552 // Result is LESS.
13563 __ Set(eax, Immediate(Smi::FromInt(LESS))); 13553 __ Set(eax, Immediate(Smi::FromInt(LESS)));
13564 __ ret(2 * kPointerSize); 13554 __ ret(0);
13565 13555
13566 // Result is GREATER. 13556 // Result is GREATER.
13567 __ bind(&result_greater); 13557 __ bind(&result_greater);
13568 __ Set(eax, Immediate(Smi::FromInt(GREATER))); 13558 __ Set(eax, Immediate(Smi::FromInt(GREATER)));
13569 __ ret(2 * kPointerSize); 13559 __ ret(0);
13570 } 13560 }
13571 13561
13572 13562
13573 void StringCompareStub::Generate(MacroAssembler* masm) { 13563 void StringCompareStub::Generate(MacroAssembler* masm) {
13574 Label runtime; 13564 Label runtime;
13575 13565
13576 // Stack frame on entry. 13566 // Stack frame on entry.
13577 // esp[0]: return address 13567 // esp[0]: return address
13578 // esp[4]: right string 13568 // esp[4]: right string
13579 // esp[8]: left string 13569 // esp[8]: left string
13580 13570
13581 __ mov(edx, Operand(esp, 2 * kPointerSize)); // left 13571 __ mov(edx, Operand(esp, 2 * kPointerSize)); // left
13582 __ mov(eax, Operand(esp, 1 * kPointerSize)); // right 13572 __ mov(eax, Operand(esp, 1 * kPointerSize)); // right
13583 13573
13584 Label not_same; 13574 Label not_same;
13585 __ cmp(edx, Operand(eax)); 13575 __ cmp(edx, Operand(eax));
13586 __ j(not_equal, &not_same); 13576 __ j(not_equal, &not_same);
13587 ASSERT_EQ(0, EQUAL); 13577 ASSERT_EQ(0, EQUAL);
13588 ASSERT_EQ(0, kSmiTag); 13578 ASSERT_EQ(0, kSmiTag);
13589 __ Set(eax, Immediate(Smi::FromInt(EQUAL))); 13579 __ Set(eax, Immediate(Smi::FromInt(EQUAL)));
13590 __ IncrementCounter(&Counters::string_compare_native, 1); 13580 __ IncrementCounter(&Counters::string_compare_native, 1);
13591 __ ret(2 * kPointerSize); 13581 __ ret(2 * kPointerSize);
13592 13582
13593 __ bind(&not_same); 13583 __ bind(&not_same);
13594 13584
13595 // Check that both objects are sequential ascii strings. 13585 // Check that both objects are sequential ascii strings.
13596 __ JumpIfNotBothSequentialAsciiStrings(edx, eax, ecx, ebx, &runtime); 13586 __ JumpIfNotBothSequentialAsciiStrings(edx, eax, ecx, ebx, &runtime);
13597 13587
13598 // Compare flat ascii strings. 13588 // Compare flat ascii strings.
13589 // Drop arguments from the stack.
13590 __ pop(ecx);
13591 __ add(Operand(esp), Immediate(2 * kPointerSize));
13592 __ push(ecx);
13599 GenerateCompareFlatAsciiStrings(masm, edx, eax, ecx, ebx, edi); 13593 GenerateCompareFlatAsciiStrings(masm, edx, eax, ecx, ebx, edi);
13600 13594
13601 // Call the runtime; it returns -1 (less), 0 (equal), or 1 (greater) 13595 // Call the runtime; it returns -1 (less), 0 (equal), or 1 (greater)
13602 // tagged as a small integer. 13596 // tagged as a small integer.
13603 __ bind(&runtime); 13597 __ bind(&runtime);
13604 __ TailCallRuntime(Runtime::kStringCompare, 2, 1); 13598 __ TailCallRuntime(Runtime::kStringCompare, 2, 1);
13605 } 13599 }
13606 13600
13607 #undef __ 13601 #undef __
13608 13602
(...skipping 198 matching lines...) Expand 10 before | Expand all | Expand 10 after
13807 masm.GetCode(&desc); 13801 masm.GetCode(&desc);
13808 // Call the function from C++. 13802 // Call the function from C++.
13809 return FUNCTION_CAST<MemCopyFunction>(buffer); 13803 return FUNCTION_CAST<MemCopyFunction>(buffer);
13810 } 13804 }
13811 13805
13812 #undef __ 13806 #undef __
13813 13807
13814 } } // namespace v8::internal 13808 } } // namespace v8::internal
13815 13809
13816 #endif // V8_TARGET_ARCH_IA32 13810 #endif // V8_TARGET_ARCH_IA32
OLDNEW
« no previous file with comments | « no previous file | src/x64/codegen-x64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698