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

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

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