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

Side by Side Diff: src/x64/codegen-x64.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 | « src/ia32/codegen-ia32.cc ('k') | no next file » | 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 10270 matching lines...) Expand 10 before | Expand all | Expand 10 after
10281 10281
10282 // Check for oddballs: true, false, null, undefined. 10282 // Check for oddballs: true, false, null, undefined.
10283 __ CmpInstanceType(rcx, ODDBALL_TYPE); 10283 __ CmpInstanceType(rcx, ODDBALL_TYPE);
10284 __ j(equal, &return_not_equal); 10284 __ j(equal, &return_not_equal);
10285 10285
10286 // Fall through to the general case. 10286 // Fall through to the general case.
10287 } 10287 }
10288 __ bind(&slow); 10288 __ bind(&slow);
10289 } 10289 }
10290 10290
10291 // Push arguments below the return address to prepare jump to builtin.
10292 __ pop(rcx);
10293 __ push(rax);
10294 __ push(rdx);
10295 __ push(rcx);
10296
10297 // Generate the number comparison code. 10291 // Generate the number comparison code.
10298 if (include_number_compare_) { 10292 if (include_number_compare_) {
10299 Label non_number_comparison; 10293 Label non_number_comparison;
10300 Label unordered; 10294 Label unordered;
10301 FloatingPointHelper::LoadSSE2UnknownOperands(masm, &non_number_comparison); 10295 FloatingPointHelper::LoadSSE2UnknownOperands(masm, &non_number_comparison);
10302 __ xorl(rax, rax); 10296 __ xorl(rax, rax);
10303 __ xorl(rcx, rcx); 10297 __ xorl(rcx, rcx);
10304 __ ucomisd(xmm0, xmm1); 10298 __ ucomisd(xmm0, xmm1);
10305 10299
10306 // Don't base result on EFLAGS when a NaN is involved. 10300 // Don't base result on EFLAGS when a NaN is involved.
10307 __ j(parity_even, &unordered); 10301 __ j(parity_even, &unordered);
10308 // Return a result of -1, 0, or 1, based on EFLAGS. 10302 // Return a result of -1, 0, or 1, based on EFLAGS.
10309 __ setcc(above, rax); 10303 __ setcc(above, rax);
10310 __ setcc(below, rcx); 10304 __ setcc(below, rcx);
10311 __ subq(rax, rcx); 10305 __ subq(rax, rcx);
10312 __ ret(2 * kPointerSize); // rax, rdx were pushed 10306 __ ret(0);
10313 10307
10314 // If one of the numbers was NaN, then the result is always false. 10308 // If one of the numbers was NaN, then the result is always false.
10315 // The cc is never not-equal. 10309 // The cc is never not-equal.
10316 __ bind(&unordered); 10310 __ bind(&unordered);
10317 ASSERT(cc_ != not_equal); 10311 ASSERT(cc_ != not_equal);
10318 if (cc_ == less || cc_ == less_equal) { 10312 if (cc_ == less || cc_ == less_equal) {
10319 __ Set(rax, 1); 10313 __ Set(rax, 1);
10320 } else { 10314 } else {
10321 __ Set(rax, -1); 10315 __ Set(rax, -1);
10322 } 10316 }
10323 __ ret(2 * kPointerSize); // rax, rdx were pushed 10317 __ ret(0);
10324 10318
10325 // The number comparison code did not provide a valid result. 10319 // The number comparison code did not provide a valid result.
10326 __ bind(&non_number_comparison); 10320 __ bind(&non_number_comparison);
10327 } 10321 }
10328 10322
10329 // Fast negative check for symbol-to-symbol equality. 10323 // Fast negative check for symbol-to-symbol equality.
10330 Label check_for_strings; 10324 Label check_for_strings;
10331 if (cc_ == equal) { 10325 if (cc_ == equal) {
10332 BranchIfNonSymbol(masm, &check_for_strings, rax, kScratchRegister); 10326 BranchIfNonSymbol(masm, &check_for_strings, rax, kScratchRegister);
10333 BranchIfNonSymbol(masm, &check_for_strings, rdx, kScratchRegister); 10327 BranchIfNonSymbol(masm, &check_for_strings, rdx, kScratchRegister);
10334 10328
10335 // We've already checked for object identity, so if both operands 10329 // We've already checked for object identity, so if both operands
10336 // are symbols they aren't equal. Register eax (not rax) already holds a 10330 // are symbols they aren't equal. Register eax (not rax) already holds a
10337 // non-zero value, which indicates not equal, so just return. 10331 // non-zero value, which indicates not equal, so just return.
10338 __ ret(2 * kPointerSize); 10332 __ ret(0);
10339 } 10333 }
10340 10334
10341 __ bind(&check_for_strings); 10335 __ bind(&check_for_strings);
10342 10336
10343 __ JumpIfNotBothSequentialAsciiStrings( 10337 __ JumpIfNotBothSequentialAsciiStrings(
10344 rdx, rax, rcx, rbx, &check_unequal_objects); 10338 rdx, rax, rcx, rbx, &check_unequal_objects);
10345 10339
10346 // Inline comparison of ascii strings. 10340 // Inline comparison of ascii strings.
10347 StringCompareStub::GenerateCompareFlatAsciiStrings(masm, 10341 StringCompareStub::GenerateCompareFlatAsciiStrings(masm,
10348 rdx, 10342 rdx,
(...skipping 30 matching lines...) Expand all
10379 __ j(zero, &return_unequal); 10373 __ j(zero, &return_unequal);
10380 __ testb(FieldOperand(rcx, Map::kBitFieldOffset), 10374 __ testb(FieldOperand(rcx, Map::kBitFieldOffset),
10381 Immediate(1 << Map::kIsUndetectable)); 10375 Immediate(1 << Map::kIsUndetectable));
10382 __ j(zero, &return_unequal); 10376 __ j(zero, &return_unequal);
10383 // The objects are both undetectable, so they both compare as the value 10377 // The objects are both undetectable, so they both compare as the value
10384 // undefined, and are equal. 10378 // undefined, and are equal.
10385 __ Set(rax, EQUAL); 10379 __ Set(rax, EQUAL);
10386 __ bind(&return_unequal); 10380 __ bind(&return_unequal);
10387 // Return non-equal by returning the non-zero object pointer in eax, 10381 // Return non-equal by returning the non-zero object pointer in eax,
10388 // or return equal if we fell through to here. 10382 // or return equal if we fell through to here.
10389 __ ret(2 * kPointerSize); // rax, rdx were pushed 10383 __ ret(0);
10390 __ bind(&not_both_objects); 10384 __ bind(&not_both_objects);
10391 } 10385 }
10392 10386
10393 // must swap argument order 10387 // Push arguments below the return address to prepare jump to builtin.
10394 __ pop(rcx); 10388 __ pop(rcx);
10395 __ pop(rdx);
10396 __ pop(rax);
10397 __ push(rdx); 10389 __ push(rdx);
10398 __ push(rax); 10390 __ push(rax);
10399 10391
10400 // Figure out which native to call and setup the arguments. 10392 // Figure out which native to call and setup the arguments.
10401 Builtins::JavaScript builtin; 10393 Builtins::JavaScript builtin;
10402 if (cc_ == equal) { 10394 if (cc_ == equal) {
10403 builtin = strict_ ? Builtins::STRICT_EQUALS : Builtins::EQUALS; 10395 builtin = strict_ ? Builtins::STRICT_EQUALS : Builtins::EQUALS;
10404 } else { 10396 } else {
10405 builtin = Builtins::COMPARE; 10397 builtin = Builtins::COMPARE;
10406 __ Push(Smi::FromInt(NegativeComparisonResult(cc_))); 10398 __ Push(Smi::FromInt(NegativeComparisonResult(cc_)));
(...skipping 1556 matching lines...) Expand 10 before | Expand all | Expand 10 after
11963 __ j(not_equal, &loop); 11955 __ j(not_equal, &loop);
11964 } 11956 }
11965 // Completed loop without finding different characters. 11957 // Completed loop without finding different characters.
11966 // Compare lengths (precomputed). 11958 // Compare lengths (precomputed).
11967 __ bind(&compare_lengths); 11959 __ bind(&compare_lengths);
11968 __ SmiTest(length_difference); 11960 __ SmiTest(length_difference);
11969 __ j(not_zero, &result_not_equal); 11961 __ j(not_zero, &result_not_equal);
11970 11962
11971 // Result is EQUAL. 11963 // Result is EQUAL.
11972 __ Move(rax, Smi::FromInt(EQUAL)); 11964 __ Move(rax, Smi::FromInt(EQUAL));
11973 __ ret(2 * kPointerSize); 11965 __ ret(0);
11974 11966
11975 Label result_greater; 11967 Label result_greater;
11976 __ bind(&result_not_equal); 11968 __ bind(&result_not_equal);
11977 // Unequal comparison of left to right, either character or length. 11969 // Unequal comparison of left to right, either character or length.
11978 __ j(greater, &result_greater); 11970 __ j(greater, &result_greater);
11979 11971
11980 // Result is LESS. 11972 // Result is LESS.
11981 __ Move(rax, Smi::FromInt(LESS)); 11973 __ Move(rax, Smi::FromInt(LESS));
11982 __ ret(2 * kPointerSize); 11974 __ ret(0);
11983 11975
11984 // Result is GREATER. 11976 // Result is GREATER.
11985 __ bind(&result_greater); 11977 __ bind(&result_greater);
11986 __ Move(rax, Smi::FromInt(GREATER)); 11978 __ Move(rax, Smi::FromInt(GREATER));
11987 __ ret(2 * kPointerSize); 11979 __ ret(0);
11988 } 11980 }
11989 11981
11990 11982
11991 void StringCompareStub::Generate(MacroAssembler* masm) { 11983 void StringCompareStub::Generate(MacroAssembler* masm) {
11992 Label runtime; 11984 Label runtime;
11993 11985
11994 // Stack frame on entry. 11986 // Stack frame on entry.
11995 // rsp[0]: return address 11987 // rsp[0]: return address
11996 // rsp[8]: right string 11988 // rsp[8]: right string
11997 // rsp[16]: left string 11989 // rsp[16]: left string
11998 11990
11999 __ movq(rdx, Operand(rsp, 2 * kPointerSize)); // left 11991 __ movq(rdx, Operand(rsp, 2 * kPointerSize)); // left
12000 __ movq(rax, Operand(rsp, 1 * kPointerSize)); // right 11992 __ movq(rax, Operand(rsp, 1 * kPointerSize)); // right
12001 11993
12002 // Check for identity. 11994 // Check for identity.
12003 Label not_same; 11995 Label not_same;
12004 __ cmpq(rdx, rax); 11996 __ cmpq(rdx, rax);
12005 __ j(not_equal, &not_same); 11997 __ j(not_equal, &not_same);
12006 __ Move(rax, Smi::FromInt(EQUAL)); 11998 __ Move(rax, Smi::FromInt(EQUAL));
12007 __ IncrementCounter(&Counters::string_compare_native, 1); 11999 __ IncrementCounter(&Counters::string_compare_native, 1);
12008 __ ret(2 * kPointerSize); 12000 __ ret(2 * kPointerSize);
12009 12001
12010 __ bind(&not_same); 12002 __ bind(&not_same);
12011 12003
12012 // Check that both are sequential ASCII strings. 12004 // Check that both are sequential ASCII strings.
12013 __ JumpIfNotBothSequentialAsciiStrings(rdx, rax, rcx, rbx, &runtime); 12005 __ JumpIfNotBothSequentialAsciiStrings(rdx, rax, rcx, rbx, &runtime);
12014 12006
12015 // Inline comparison of ascii strings. 12007 // Inline comparison of ascii strings.
12016 __ IncrementCounter(&Counters::string_compare_native, 1); 12008 __ IncrementCounter(&Counters::string_compare_native, 1);
12009 // Drop arguments from the stack
12010 __ pop(rcx);
12011 __ addq(rsp, Immediate(2 * kPointerSize));
12012 __ push(rcx);
12017 GenerateCompareFlatAsciiStrings(masm, rdx, rax, rcx, rbx, rdi, r8); 12013 GenerateCompareFlatAsciiStrings(masm, rdx, rax, rcx, rbx, rdi, r8);
12018 12014
12019 // Call the runtime; it returns -1 (less), 0 (equal), or 1 (greater) 12015 // Call the runtime; it returns -1 (less), 0 (equal), or 1 (greater)
12020 // tagged as a small integer. 12016 // tagged as a small integer.
12021 __ bind(&runtime); 12017 __ bind(&runtime);
12022 __ TailCallRuntime(Runtime::kStringCompare, 2, 1); 12018 __ TailCallRuntime(Runtime::kStringCompare, 2, 1);
12023 } 12019 }
12024 12020
12025 #undef __ 12021 #undef __
12026 12022
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
12119 #undef __ 12115 #undef __
12120 12116
12121 void RecordWriteStub::Generate(MacroAssembler* masm) { 12117 void RecordWriteStub::Generate(MacroAssembler* masm) {
12122 masm->RecordWriteHelper(object_, addr_, scratch_); 12118 masm->RecordWriteHelper(object_, addr_, scratch_);
12123 masm->ret(0); 12119 masm->ret(0);
12124 } 12120 }
12125 12121
12126 } } // namespace v8::internal 12122 } } // namespace v8::internal
12127 12123
12128 #endif // V8_TARGET_ARCH_X64 12124 #endif // V8_TARGET_ARCH_X64
OLDNEW
« no previous file with comments | « src/ia32/codegen-ia32.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698