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

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

Issue 6682026: Fix SmiCompare on 64 bit to distinguish between comparisons where... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: Created 9 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
OLDNEW
1 // Copyright 2011 the V8 project authors. All rights reserved. 1 // Copyright 2011 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 748 matching lines...) Expand 10 before | Expand all | Expand 10 after
759 // The value to convert should be popped from the frame. 759 // The value to convert should be popped from the frame.
760 Result value = frame_->Pop(); 760 Result value = frame_->Pop();
761 value.ToRegister(); 761 value.ToRegister();
762 762
763 if (value.is_number()) { 763 if (value.is_number()) {
764 // Fast case if TypeInfo indicates only numbers. 764 // Fast case if TypeInfo indicates only numbers.
765 if (FLAG_debug_code) { 765 if (FLAG_debug_code) {
766 __ AbortIfNotNumber(value.reg()); 766 __ AbortIfNotNumber(value.reg());
767 } 767 }
768 // Smi => false iff zero. 768 // Smi => false iff zero.
769 __ SmiCompare(value.reg(), Smi::FromInt(0)); 769 __ SmiCompareWithObject(value.reg(), Smi::FromInt(0));
770 if (value.is_smi()) { 770 if (value.is_smi()) {
771 value.Unuse(); 771 value.Unuse();
772 dest->Split(not_zero); 772 dest->Split(not_zero);
773 } else { 773 } else {
774 dest->false_target()->Branch(equal); 774 dest->false_target()->Branch(equal);
775 Condition is_smi = masm_->CheckSmi(value.reg()); 775 Condition is_smi = masm_->CheckSmi(value.reg());
776 dest->true_target()->Branch(is_smi); 776 dest->true_target()->Branch(is_smi);
777 __ xorpd(xmm0, xmm0); 777 __ xorpd(xmm0, xmm0);
778 __ ucomisd(xmm0, FieldOperand(value.reg(), HeapNumber::kValueOffset)); 778 __ ucomisd(xmm0, FieldOperand(value.reg(), HeapNumber::kValueOffset));
779 value.Unuse(); 779 value.Unuse();
780 dest->Split(not_zero); 780 dest->Split(not_zero);
781 } 781 }
782 } else { 782 } else {
783 // Fast case checks. 783 // Fast case checks.
784 // 'false' => false. 784 // 'false' => false.
785 __ CompareRoot(value.reg(), Heap::kFalseValueRootIndex); 785 __ CompareRoot(value.reg(), Heap::kFalseValueRootIndex);
786 dest->false_target()->Branch(equal); 786 dest->false_target()->Branch(equal);
787 787
788 // 'true' => true. 788 // 'true' => true.
789 __ CompareRoot(value.reg(), Heap::kTrueValueRootIndex); 789 __ CompareRoot(value.reg(), Heap::kTrueValueRootIndex);
790 dest->true_target()->Branch(equal); 790 dest->true_target()->Branch(equal);
791 791
792 // 'undefined' => false. 792 // 'undefined' => false.
793 __ CompareRoot(value.reg(), Heap::kUndefinedValueRootIndex); 793 __ CompareRoot(value.reg(), Heap::kUndefinedValueRootIndex);
794 dest->false_target()->Branch(equal); 794 dest->false_target()->Branch(equal);
795 795
796 // Smi => false iff zero. 796 // Smi => false iff zero.
797 __ SmiCompare(value.reg(), Smi::FromInt(0)); 797 __ SmiCompareWithObject(value.reg(), Smi::FromInt(0));
798 dest->false_target()->Branch(equal); 798 dest->false_target()->Branch(equal);
799 Condition is_smi = masm_->CheckSmi(value.reg()); 799 Condition is_smi = masm_->CheckSmi(value.reg());
800 dest->true_target()->Branch(is_smi); 800 dest->true_target()->Branch(is_smi);
801 801
802 // Call the stub for all other cases. 802 // Call the stub for all other cases.
803 frame_->Push(&value); // Undo the Pop() from above. 803 frame_->Push(&value); // Undo the Pop() from above.
804 ToBooleanStub stub; 804 ToBooleanStub stub;
805 Result temp = frame_->CallStub(&stub, 1); 805 Result temp = frame_->CallStub(&stub, 1);
806 // Convert the result to a condition code. 806 // Convert the result to a condition code.
807 __ testq(temp.reg(), temp.reg()); 807 __ testq(temp.reg(), temp.reg());
(...skipping 1293 matching lines...) Expand 10 before | Expand all | Expand 10 after
2101 is_string.Bind(&left_side); 2101 is_string.Bind(&left_side);
2102 // left_side is a sequential ASCII string. 2102 // left_side is a sequential ASCII string.
2103 ASSERT(left_side.reg().is(left_reg)); 2103 ASSERT(left_side.reg().is(left_reg));
2104 right_side = Result(right_val); 2104 right_side = Result(right_val);
2105 Result temp2 = allocator_->Allocate(); 2105 Result temp2 = allocator_->Allocate();
2106 ASSERT(temp2.is_valid()); 2106 ASSERT(temp2.is_valid());
2107 // Test string equality and comparison. 2107 // Test string equality and comparison.
2108 if (cc == equal) { 2108 if (cc == equal) {
2109 Label comparison_done; 2109 Label comparison_done;
2110 __ SmiCompare(FieldOperand(left_side.reg(), String::kLengthOffset), 2110 __ SmiCompare(FieldOperand(left_side.reg(), String::kLengthOffset),
2111 Smi::FromInt(1)); 2111 Smi::FromInt(1));
2112 __ j(not_equal, &comparison_done); 2112 __ j(not_equal, &comparison_done);
2113 uint8_t char_value = 2113 uint8_t char_value =
2114 static_cast<uint8_t>(String::cast(*right_val)->Get(0)); 2114 static_cast<uint8_t>(String::cast(*right_val)->Get(0));
2115 __ cmpb(FieldOperand(left_side.reg(), SeqAsciiString::kHeaderSize), 2115 __ cmpb(FieldOperand(left_side.reg(), SeqAsciiString::kHeaderSize),
2116 Immediate(char_value)); 2116 Immediate(char_value));
2117 __ bind(&comparison_done); 2117 __ bind(&comparison_done);
2118 } else { 2118 } else {
2119 __ movq(temp2.reg(), 2119 __ movq(temp2.reg(),
2120 FieldOperand(left_side.reg(), String::kLengthOffset)); 2120 FieldOperand(left_side.reg(), String::kLengthOffset));
2121 __ SmiSubConstant(temp2.reg(), temp2.reg(), Smi::FromInt(1)); 2121 __ SmiSubConstant(temp2.reg(), temp2.reg(), Smi::FromInt(1));
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after
2239 dest->false_target()->Jump(); 2239 dest->false_target()->Jump();
2240 } else { 2240 } else {
2241 dest->Split(cc); 2241 dest->Split(cc);
2242 } 2242 }
2243 } 2243 }
2244 2244
2245 if (is_smi.is_linked()) { 2245 if (is_smi.is_linked()) {
2246 is_smi.Bind(); 2246 is_smi.Bind();
2247 left_side = Result(left_reg); 2247 left_side = Result(left_reg);
2248 right_side = Result(right_reg); 2248 right_side = Result(right_reg);
2249 __ SmiCompare(left_side.reg(), right_side.reg()); 2249 __ cmpq(left_side.reg(), right_side.reg());
Lasse Reichstein 2011/03/14 08:51:01 Why not SmiCompare? You are assuming the layout of
Erik Corry 2011/03/14 16:26:45 Done.
2250 right_side.Unuse(); 2250 right_side.Unuse();
2251 left_side.Unuse(); 2251 left_side.Unuse();
2252 dest->Split(cc); 2252 dest->Split(cc);
2253 } 2253 }
2254 } 2254 }
2255 } 2255 }
2256 } 2256 }
2257 2257
2258 2258
2259 void CodeGenerator::ConstantSmiComparison(Condition cc, 2259 void CodeGenerator::ConstantSmiComparison(Condition cc,
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
2297 // where both sides are Smis. 2297 // where both sides are Smis.
2298 left_side->ToRegister(); 2298 left_side->ToRegister();
2299 Register left_reg = left_side->reg(); 2299 Register left_reg = left_side->reg();
2300 Smi* constant_smi = Smi::cast(*right_side->handle()); 2300 Smi* constant_smi = Smi::cast(*right_side->handle());
2301 2301
2302 if (left_side->is_smi()) { 2302 if (left_side->is_smi()) {
2303 if (FLAG_debug_code) { 2303 if (FLAG_debug_code) {
2304 __ AbortIfNotSmi(left_reg); 2304 __ AbortIfNotSmi(left_reg);
2305 } 2305 }
2306 // Test smi equality and comparison by signed int comparison. 2306 // Test smi equality and comparison by signed int comparison.
2307 // Both sides are smis, so we can use an Immediate.
2308 __ SmiCompare(left_reg, constant_smi); 2307 __ SmiCompare(left_reg, constant_smi);
2309 left_side->Unuse(); 2308 left_side->Unuse();
2310 right_side->Unuse(); 2309 right_side->Unuse();
2311 dest->Split(cc); 2310 dest->Split(cc);
2312 } else { 2311 } else {
2313 // Only the case where the left side could possibly be a non-smi is left. 2312 // Only the case where the left side could possibly be a non-smi is left.
2314 JumpTarget is_smi; 2313 JumpTarget is_smi;
2315 if (cc == equal) { 2314 if (cc == equal) {
2316 // We can do the equality comparison before the smi check. 2315 // We can do the equality comparison before the smi check.
2317 __ SmiCompare(left_reg, constant_smi); 2316 __ SmiCompareWithObject(left_reg, constant_smi);
2318 dest->true_target()->Branch(equal); 2317 dest->true_target()->Branch(equal);
2319 Condition left_is_smi = masm_->CheckSmi(left_reg); 2318 Condition left_is_smi = masm_->CheckSmi(left_reg);
2320 dest->false_target()->Branch(left_is_smi); 2319 dest->false_target()->Branch(left_is_smi);
2321 } else { 2320 } else {
2322 // Do the smi check, then the comparison. 2321 // Do the smi check, then the comparison.
2323 Condition left_is_smi = masm_->CheckSmi(left_reg); 2322 Condition left_is_smi = masm_->CheckSmi(left_reg);
2324 is_smi.Branch(left_is_smi, left_side, right_side); 2323 is_smi.Branch(left_is_smi, left_side, right_side);
2325 } 2324 }
2326 2325
2327 // Jump or fall through to here if we are comparing a non-smi to a 2326 // Jump or fall through to here if we are comparing a non-smi to a
(...skipping 240 matching lines...) Expand 10 before | Expand all | Expand 10 after
2568 __ movq(rdi, Operand(rsp, 2 * kPointerSize)); 2567 __ movq(rdi, Operand(rsp, 2 * kPointerSize));
2569 is_smi = masm_->CheckSmi(rdi); 2568 is_smi = masm_->CheckSmi(rdi);
2570 __ j(is_smi, &build_args); 2569 __ j(is_smi, &build_args);
2571 __ CmpObjectType(rdi, JS_FUNCTION_TYPE, rcx); 2570 __ CmpObjectType(rdi, JS_FUNCTION_TYPE, rcx);
2572 __ j(not_equal, &build_args); 2571 __ j(not_equal, &build_args);
2573 2572
2574 // Copy the arguments to this function possibly from the 2573 // Copy the arguments to this function possibly from the
2575 // adaptor frame below it. 2574 // adaptor frame below it.
2576 Label invoke, adapted; 2575 Label invoke, adapted;
2577 __ movq(rdx, Operand(rbp, StandardFrameConstants::kCallerFPOffset)); 2576 __ movq(rdx, Operand(rbp, StandardFrameConstants::kCallerFPOffset));
2578 __ SmiCompare(Operand(rdx, StandardFrameConstants::kContextOffset), 2577 __ SmiCompareWithObject(
2579 Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR)); 2578 Operand(rdx, StandardFrameConstants::kContextOffset),
2579 Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR));
2580 __ j(equal, &adapted); 2580 __ j(equal, &adapted);
2581 2581
2582 // No arguments adaptor frame. Copy fixed number of arguments. 2582 // No arguments adaptor frame. Copy fixed number of arguments.
2583 __ Set(rax, scope()->num_parameters()); 2583 __ Set(rax, scope()->num_parameters());
2584 for (int i = 0; i < scope()->num_parameters(); i++) { 2584 for (int i = 0; i < scope()->num_parameters(); i++) {
2585 __ push(frame_->ParameterAt(i)); 2585 __ push(frame_->ParameterAt(i));
2586 } 2586 }
2587 __ jmp(&invoke); 2587 __ jmp(&invoke);
2588 2588
2589 // Arguments adaptor frame present. Copy arguments from there, but 2589 // Arguments adaptor frame present. Copy arguments from there, but
(...skipping 1260 matching lines...) Expand 10 before | Expand all | Expand 10 after
3850 __ cmpq(rcx, rdx); 3850 __ cmpq(rcx, rdx);
3851 end_del_check.Branch(equal); 3851 end_del_check.Branch(equal);
3852 3852
3853 // Convert the entry to a string (or null if it isn't a property anymore). 3853 // Convert the entry to a string (or null if it isn't a property anymore).
3854 frame_->EmitPush(frame_->ElementAt(4)); // push enumerable 3854 frame_->EmitPush(frame_->ElementAt(4)); // push enumerable
3855 frame_->EmitPush(rbx); // push entry 3855 frame_->EmitPush(rbx); // push entry
3856 frame_->InvokeBuiltin(Builtins::FILTER_KEY, CALL_FUNCTION, 2); 3856 frame_->InvokeBuiltin(Builtins::FILTER_KEY, CALL_FUNCTION, 2);
3857 __ movq(rbx, rax); 3857 __ movq(rbx, rax);
3858 3858
3859 // If the property has been removed while iterating, we just skip it. 3859 // If the property has been removed while iterating, we just skip it.
3860 __ SmiCompare(rbx, Smi::FromInt(0)); 3860 __ SmiCompareWithObject(rbx, Smi::FromInt(0));
3861 node->continue_target()->Branch(equal); 3861 node->continue_target()->Branch(equal);
3862 3862
3863 end_del_check.Bind(); 3863 end_del_check.Bind();
3864 // Store the entry in the 'each' expression and take another spin in the 3864 // Store the entry in the 'each' expression and take another spin in the
3865 // loop. rdx: i'th entry of the enum cache (or string there of) 3865 // loop. rdx: i'th entry of the enum cache (or string there of)
3866 frame_->EmitPush(rbx); 3866 frame_->EmitPush(rbx);
3867 { Reference each(this, node->each()); 3867 { Reference each(this, node->each());
3868 // Loading a reference may leave the frame in an unspilled state. 3868 // Loading a reference may leave the frame in an unspilled state.
3869 frame_->SpillAll(); 3869 frame_->SpillAll();
3870 if (!each.is_illegal()) { 3870 if (!each.is_illegal()) {
(...skipping 2320 matching lines...) Expand 10 before | Expand all | Expand 10 after
6191 6191
6192 void CodeGenerator::GenerateIsConstructCall(ZoneList<Expression*>* args) { 6192 void CodeGenerator::GenerateIsConstructCall(ZoneList<Expression*>* args) {
6193 ASSERT(args->length() == 0); 6193 ASSERT(args->length() == 0);
6194 6194
6195 // Get the frame pointer for the calling frame. 6195 // Get the frame pointer for the calling frame.
6196 Result fp = allocator()->Allocate(); 6196 Result fp = allocator()->Allocate();
6197 __ movq(fp.reg(), Operand(rbp, StandardFrameConstants::kCallerFPOffset)); 6197 __ movq(fp.reg(), Operand(rbp, StandardFrameConstants::kCallerFPOffset));
6198 6198
6199 // Skip the arguments adaptor frame if it exists. 6199 // Skip the arguments adaptor frame if it exists.
6200 Label check_frame_marker; 6200 Label check_frame_marker;
6201 __ SmiCompare(Operand(fp.reg(), StandardFrameConstants::kContextOffset), 6201 __ SmiCompareWithObject(
6202 Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR)); 6202 Operand(fp.reg(), StandardFrameConstants::kContextOffset),
6203 Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR));
6203 __ j(not_equal, &check_frame_marker); 6204 __ j(not_equal, &check_frame_marker);
6204 __ movq(fp.reg(), Operand(fp.reg(), StandardFrameConstants::kCallerFPOffset)); 6205 __ movq(fp.reg(), Operand(fp.reg(), StandardFrameConstants::kCallerFPOffset));
6205 6206
6206 // Check the marker in the calling frame. 6207 // Check the marker in the calling frame.
6207 __ bind(&check_frame_marker); 6208 __ bind(&check_frame_marker);
6208 __ SmiCompare(Operand(fp.reg(), StandardFrameConstants::kMarkerOffset), 6209 __ SmiCompareWithObject(
6209 Smi::FromInt(StackFrame::CONSTRUCT)); 6210 Operand(fp.reg(), StandardFrameConstants::kMarkerOffset),
6211 Smi::FromInt(StackFrame::CONSTRUCT));
6210 fp.Unuse(); 6212 fp.Unuse();
6211 destination()->Split(equal); 6213 destination()->Split(equal);
6212 } 6214 }
6213 6215
6214 6216
6215 void CodeGenerator::GenerateArgumentsLength(ZoneList<Expression*>* args) { 6217 void CodeGenerator::GenerateArgumentsLength(ZoneList<Expression*>* args) {
6216 ASSERT(args->length() == 0); 6218 ASSERT(args->length() == 0);
6217 6219
6218 Result fp = allocator_->Allocate(); 6220 Result fp = allocator_->Allocate();
6219 Result result = allocator_->Allocate(); 6221 Result result = allocator_->Allocate();
6220 ASSERT(fp.is_valid() && result.is_valid()); 6222 ASSERT(fp.is_valid() && result.is_valid());
6221 6223
6222 Label exit; 6224 Label exit;
6223 6225
6224 // Get the number of formal parameters. 6226 // Get the number of formal parameters.
6225 __ Move(result.reg(), Smi::FromInt(scope()->num_parameters())); 6227 __ Move(result.reg(), Smi::FromInt(scope()->num_parameters()));
6226 6228
6227 // Check if the calling frame is an arguments adaptor frame. 6229 // Check if the calling frame is an arguments adaptor frame.
6228 __ movq(fp.reg(), Operand(rbp, StandardFrameConstants::kCallerFPOffset)); 6230 __ movq(fp.reg(), Operand(rbp, StandardFrameConstants::kCallerFPOffset));
6229 __ SmiCompare(Operand(fp.reg(), StandardFrameConstants::kContextOffset), 6231 __ SmiCompareWithObject(
6230 Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR)); 6232 Operand(fp.reg(), StandardFrameConstants::kContextOffset),
6233 Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR));
6231 __ j(not_equal, &exit); 6234 __ j(not_equal, &exit);
6232 6235
6233 // Arguments adaptor case: Read the arguments length from the 6236 // Arguments adaptor case: Read the arguments length from the
6234 // adaptor frame. 6237 // adaptor frame.
6235 __ movq(result.reg(), 6238 __ movq(result.reg(),
6236 Operand(fp.reg(), ArgumentsAdaptorFrameConstants::kLengthOffset)); 6239 Operand(fp.reg(), ArgumentsAdaptorFrameConstants::kLengthOffset));
6237 6240
6238 __ bind(&exit); 6241 __ bind(&exit);
6239 result.set_type_info(TypeInfo::Smi()); 6242 result.set_type_info(TypeInfo::Smi());
6240 if (FLAG_debug_code) { 6243 if (FLAG_debug_code) {
(...skipping 553 matching lines...) Expand 10 before | Expand all | Expand 10 after
6794 __ CompareRoot(FieldOperand(tmp1.reg(), HeapObject::kMapOffset), 6797 __ CompareRoot(FieldOperand(tmp1.reg(), HeapObject::kMapOffset),
6795 Heap::kFixedArrayMapRootIndex); 6798 Heap::kFixedArrayMapRootIndex);
6796 deferred->Branch(not_equal); 6799 deferred->Branch(not_equal);
6797 6800
6798 // Check that both indices are smis. 6801 // Check that both indices are smis.
6799 Condition both_smi = masm()->CheckBothSmi(index1.reg(), index2.reg()); 6802 Condition both_smi = masm()->CheckBothSmi(index1.reg(), index2.reg());
6800 deferred->Branch(NegateCondition(both_smi)); 6803 deferred->Branch(NegateCondition(both_smi));
6801 6804
6802 // Check that both indices are valid. 6805 // Check that both indices are valid.
6803 __ movq(tmp2.reg(), FieldOperand(object.reg(), JSArray::kLengthOffset)); 6806 __ movq(tmp2.reg(), FieldOperand(object.reg(), JSArray::kLengthOffset));
6804 __ SmiCompare(tmp2.reg(), index1.reg()); 6807 __ cmpq(tmp2.reg(), index1.reg());
6805 deferred->Branch(below_equal); 6808 deferred->Branch(below_equal);
6806 __ SmiCompare(tmp2.reg(), index2.reg()); 6809 __ cmpq(tmp2.reg(), index2.reg());
6807 deferred->Branch(below_equal); 6810 deferred->Branch(below_equal);
Lasse Reichstein 2011/03/14 08:51:01 Do use SmiCompare!
Erik Corry 2011/03/14 16:26:45 Done.
6808 6811
6809 // Bring addresses into index1 and index2. 6812 // Bring addresses into index1 and index2.
6810 __ SmiToInteger32(index1.reg(), index1.reg()); 6813 __ SmiToInteger32(index1.reg(), index1.reg());
6811 __ lea(index1.reg(), FieldOperand(tmp1.reg(), 6814 __ lea(index1.reg(), FieldOperand(tmp1.reg(),
6812 index1.reg(), 6815 index1.reg(),
6813 times_pointer_size, 6816 times_pointer_size,
6814 FixedArray::kHeaderSize)); 6817 FixedArray::kHeaderSize));
6815 __ SmiToInteger32(index2.reg(), index2.reg()); 6818 __ SmiToInteger32(index2.reg(), index2.reg());
6816 __ lea(index2.reg(), FieldOperand(tmp1.reg(), 6819 __ lea(index2.reg(), FieldOperand(tmp1.reg(),
6817 index2.reg(), 6820 index2.reg(),
(...skipping 2016 matching lines...) Expand 10 before | Expand all | Expand 10 after
8834 } 8837 }
8835 8838
8836 #endif 8839 #endif
8837 8840
8838 8841
8839 #undef __ 8842 #undef __
8840 8843
8841 } } // namespace v8::internal 8844 } } // namespace v8::internal
8842 8845
8843 #endif // V8_TARGET_ARCH_X64 8846 #endif // V8_TARGET_ARCH_X64
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698