| OLD | NEW |
| 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 258 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 269 // Get the map and type of the heap object. | 269 // Get the map and type of the heap object. |
| 270 __ mov(edx, FieldOperand(eax, HeapObject::kMapOffset)); | 270 __ mov(edx, FieldOperand(eax, HeapObject::kMapOffset)); |
| 271 __ movzx_b(ecx, FieldOperand(edx, Map::kInstanceTypeOffset)); | 271 __ movzx_b(ecx, FieldOperand(edx, Map::kInstanceTypeOffset)); |
| 272 | 272 |
| 273 // Undetectable => false. | 273 // Undetectable => false. |
| 274 __ test_b(FieldOperand(edx, Map::kBitFieldOffset), | 274 __ test_b(FieldOperand(edx, Map::kBitFieldOffset), |
| 275 1 << Map::kIsUndetectable); | 275 1 << Map::kIsUndetectable); |
| 276 __ j(not_zero, &false_result, Label::kNear); | 276 __ j(not_zero, &false_result, Label::kNear); |
| 277 | 277 |
| 278 // JavaScript object => true. | 278 // JavaScript object => true. |
| 279 __ CmpInstanceType(edx, FIRST_JS_OBJECT_TYPE); | 279 __ CmpInstanceType(edx, FIRST_OBJECT_OR_FUNCTION_CLASS_TYPE); |
| 280 __ j(above_equal, &true_result, Label::kNear); | 280 __ j(above_equal, &true_result, Label::kNear); |
| 281 | 281 |
| 282 // String value => false iff empty. | 282 // String value => false iff empty. |
| 283 __ CmpInstanceType(edx, FIRST_NONSTRING_TYPE); | 283 __ CmpInstanceType(edx, FIRST_NONSTRING_TYPE); |
| 284 __ j(above_equal, ¬_string, Label::kNear); | 284 __ j(above_equal, ¬_string, Label::kNear); |
| 285 STATIC_ASSERT(kSmiTag == 0); | 285 STATIC_ASSERT(kSmiTag == 0); |
| 286 __ cmp(FieldOperand(eax, String::kLengthOffset), Immediate(0)); | 286 __ cmp(FieldOperand(eax, String::kLengthOffset), Immediate(0)); |
| 287 __ j(zero, &false_result, Label::kNear); | 287 __ j(zero, &false_result, Label::kNear); |
| 288 __ jmp(&true_result, Label::kNear); | 288 __ jmp(&true_result, Label::kNear); |
| 289 | 289 |
| (...skipping 3358 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3648 if (never_nan_nan_ && (cc_ == equal)) { | 3648 if (never_nan_nan_ && (cc_ == equal)) { |
| 3649 __ Set(eax, Immediate(Smi::FromInt(EQUAL))); | 3649 __ Set(eax, Immediate(Smi::FromInt(EQUAL))); |
| 3650 __ ret(0); | 3650 __ ret(0); |
| 3651 } else { | 3651 } else { |
| 3652 Label heap_number; | 3652 Label heap_number; |
| 3653 __ cmp(FieldOperand(edx, HeapObject::kMapOffset), | 3653 __ cmp(FieldOperand(edx, HeapObject::kMapOffset), |
| 3654 Immediate(masm->isolate()->factory()->heap_number_map())); | 3654 Immediate(masm->isolate()->factory()->heap_number_map())); |
| 3655 __ j(equal, &heap_number, Label::kNear); | 3655 __ j(equal, &heap_number, Label::kNear); |
| 3656 if (cc_ != equal) { | 3656 if (cc_ != equal) { |
| 3657 // Call runtime on identical JSObjects. Otherwise return equal. | 3657 // Call runtime on identical JSObjects. Otherwise return equal. |
| 3658 __ CmpObjectType(eax, FIRST_JS_OBJECT_TYPE, ecx); | 3658 __ CmpObjectType(eax, FIRST_OBJECT_OR_FUNCTION_CLASS_TYPE, ecx); |
| 3659 __ j(above_equal, ¬_identical); | 3659 __ j(above_equal, ¬_identical); |
| 3660 } | 3660 } |
| 3661 __ Set(eax, Immediate(Smi::FromInt(EQUAL))); | 3661 __ Set(eax, Immediate(Smi::FromInt(EQUAL))); |
| 3662 __ ret(0); | 3662 __ ret(0); |
| 3663 | 3663 |
| 3664 __ bind(&heap_number); | 3664 __ bind(&heap_number); |
| 3665 // It is a heap number, so return non-equal if it's NaN and equal if | 3665 // It is a heap number, so return non-equal if it's NaN and equal if |
| 3666 // it's not NaN. | 3666 // it's not NaN. |
| 3667 // The representation of NaN values has all exponent bits (52..62) set, | 3667 // The representation of NaN values has all exponent bits (52..62) set, |
| 3668 // and not all mantissa bits (0..51) clear. | 3668 // and not all mantissa bits (0..51) clear. |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3736 __ ret(0); | 3736 __ ret(0); |
| 3737 | 3737 |
| 3738 __ bind(¬_smis); | 3738 __ bind(¬_smis); |
| 3739 // If either operand is a JSObject or an oddball value, then they are not | 3739 // If either operand is a JSObject or an oddball value, then they are not |
| 3740 // equal since their pointers are different | 3740 // equal since their pointers are different |
| 3741 // There is no test for undetectability in strict equality. | 3741 // There is no test for undetectability in strict equality. |
| 3742 | 3742 |
| 3743 // Get the type of the first operand. | 3743 // Get the type of the first operand. |
| 3744 // If the first object is a JS object, we have done pointer comparison. | 3744 // If the first object is a JS object, we have done pointer comparison. |
| 3745 Label first_non_object; | 3745 Label first_non_object; |
| 3746 STATIC_ASSERT(LAST_TYPE == JS_FUNCTION_TYPE); | 3746 STATIC_ASSERT(LAST_TYPE == LAST_OBJECT_OR_FUNCTION_CLASS_TYPE); |
| 3747 __ CmpObjectType(eax, FIRST_JS_OBJECT_TYPE, ecx); | 3747 __ CmpObjectType(eax, FIRST_OBJECT_OR_FUNCTION_CLASS_TYPE, ecx); |
| 3748 __ j(below, &first_non_object, Label::kNear); | 3748 __ j(below, &first_non_object, Label::kNear); |
| 3749 | 3749 |
| 3750 // Return non-zero (eax is not zero) | 3750 // Return non-zero (eax is not zero) |
| 3751 Label return_not_equal; | 3751 Label return_not_equal; |
| 3752 STATIC_ASSERT(kHeapObjectTag != 0); | 3752 STATIC_ASSERT(kHeapObjectTag != 0); |
| 3753 __ bind(&return_not_equal); | 3753 __ bind(&return_not_equal); |
| 3754 __ ret(0); | 3754 __ ret(0); |
| 3755 | 3755 |
| 3756 __ bind(&first_non_object); | 3756 __ bind(&first_non_object); |
| 3757 // Check for oddballs: true, false, null, undefined. | 3757 // Check for oddballs: true, false, null, undefined. |
| 3758 __ CmpInstanceType(ecx, ODDBALL_TYPE); | 3758 __ CmpInstanceType(ecx, ODDBALL_TYPE); |
| 3759 __ j(equal, &return_not_equal); | 3759 __ j(equal, &return_not_equal); |
| 3760 | 3760 |
| 3761 __ CmpObjectType(edx, FIRST_JS_OBJECT_TYPE, ecx); | 3761 __ CmpObjectType(edx, FIRST_OBJECT_OR_FUNCTION_CLASS_TYPE, ecx); |
| 3762 __ j(above_equal, &return_not_equal); | 3762 __ j(above_equal, &return_not_equal); |
| 3763 | 3763 |
| 3764 // Check for oddballs: true, false, null, undefined. | 3764 // Check for oddballs: true, false, null, undefined. |
| 3765 __ CmpInstanceType(ecx, ODDBALL_TYPE); | 3765 __ CmpInstanceType(ecx, ODDBALL_TYPE); |
| 3766 __ j(equal, &return_not_equal); | 3766 __ j(equal, &return_not_equal); |
| 3767 | 3767 |
| 3768 // Fall through to the general case. | 3768 // Fall through to the general case. |
| 3769 __ bind(&slow); | 3769 __ bind(&slow); |
| 3770 } | 3770 } |
| 3771 | 3771 |
| (...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3875 Label not_both_objects; | 3875 Label not_both_objects; |
| 3876 Label return_unequal; | 3876 Label return_unequal; |
| 3877 // At most one is a smi, so we can test for smi by adding the two. | 3877 // At most one is a smi, so we can test for smi by adding the two. |
| 3878 // A smi plus a heap object has the low bit set, a heap object plus | 3878 // A smi plus a heap object has the low bit set, a heap object plus |
| 3879 // a heap object has the low bit clear. | 3879 // a heap object has the low bit clear. |
| 3880 STATIC_ASSERT(kSmiTag == 0); | 3880 STATIC_ASSERT(kSmiTag == 0); |
| 3881 STATIC_ASSERT(kSmiTagMask == 1); | 3881 STATIC_ASSERT(kSmiTagMask == 1); |
| 3882 __ lea(ecx, Operand(eax, edx, times_1, 0)); | 3882 __ lea(ecx, Operand(eax, edx, times_1, 0)); |
| 3883 __ test(ecx, Immediate(kSmiTagMask)); | 3883 __ test(ecx, Immediate(kSmiTagMask)); |
| 3884 __ j(not_zero, ¬_both_objects, Label::kNear); | 3884 __ j(not_zero, ¬_both_objects, Label::kNear); |
| 3885 __ CmpObjectType(eax, FIRST_JS_OBJECT_TYPE, ecx); | 3885 __ CmpObjectType(eax, FIRST_OBJECT_OR_FUNCTION_CLASS_TYPE, ecx); |
| 3886 __ j(below, ¬_both_objects, Label::kNear); | 3886 __ j(below, ¬_both_objects, Label::kNear); |
| 3887 __ CmpObjectType(edx, FIRST_JS_OBJECT_TYPE, ebx); | 3887 __ CmpObjectType(edx, FIRST_OBJECT_OR_FUNCTION_CLASS_TYPE, ebx); |
| 3888 __ j(below, ¬_both_objects, Label::kNear); | 3888 __ j(below, ¬_both_objects, Label::kNear); |
| 3889 // We do not bail out after this point. Both are JSObjects, and | 3889 // We do not bail out after this point. Both are JSObjects, and |
| 3890 // they are equal if and only if both are undetectable. | 3890 // they are equal if and only if both are undetectable. |
| 3891 // The and of the undetectable flags is 1 if and only if they are equal. | 3891 // The and of the undetectable flags is 1 if and only if they are equal. |
| 3892 __ test_b(FieldOperand(ecx, Map::kBitFieldOffset), | 3892 __ test_b(FieldOperand(ecx, Map::kBitFieldOffset), |
| 3893 1 << Map::kIsUndetectable); | 3893 1 << Map::kIsUndetectable); |
| 3894 __ j(zero, &return_unequal, Label::kNear); | 3894 __ j(zero, &return_unequal, Label::kNear); |
| 3895 __ test_b(FieldOperand(ebx, Map::kBitFieldOffset), | 3895 __ test_b(FieldOperand(ebx, Map::kBitFieldOffset), |
| 3896 1 << Map::kIsUndetectable); | 3896 1 << Map::kIsUndetectable); |
| 3897 __ j(zero, &return_unequal, Label::kNear); | 3897 __ j(zero, &return_unequal, Label::kNear); |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3956 // Get the receiver from the stack. | 3956 // Get the receiver from the stack. |
| 3957 // +1 ~ return address | 3957 // +1 ~ return address |
| 3958 Label receiver_is_value, receiver_is_js_object; | 3958 Label receiver_is_value, receiver_is_js_object; |
| 3959 __ mov(eax, Operand(esp, (argc_ + 1) * kPointerSize)); | 3959 __ mov(eax, Operand(esp, (argc_ + 1) * kPointerSize)); |
| 3960 | 3960 |
| 3961 // Check if receiver is a smi (which is a number value). | 3961 // Check if receiver is a smi (which is a number value). |
| 3962 __ test(eax, Immediate(kSmiTagMask)); | 3962 __ test(eax, Immediate(kSmiTagMask)); |
| 3963 __ j(zero, &receiver_is_value); | 3963 __ j(zero, &receiver_is_value); |
| 3964 | 3964 |
| 3965 // Check if the receiver is a valid JS object. | 3965 // Check if the receiver is a valid JS object. |
| 3966 __ CmpObjectType(eax, FIRST_JS_OBJECT_TYPE, edi); | 3966 __ CmpObjectType(eax, FIRST_OBJECT_OR_FUNCTION_CLASS_TYPE, edi); |
| 3967 __ j(above_equal, &receiver_is_js_object); | 3967 __ j(above_equal, &receiver_is_js_object); |
| 3968 | 3968 |
| 3969 // Call the runtime to box the value. | 3969 // Call the runtime to box the value. |
| 3970 __ bind(&receiver_is_value); | 3970 __ bind(&receiver_is_value); |
| 3971 __ EnterInternalFrame(); | 3971 __ EnterInternalFrame(); |
| 3972 __ push(eax); | 3972 __ push(eax); |
| 3973 __ InvokeBuiltin(Builtins::TO_OBJECT, CALL_FUNCTION); | 3973 __ InvokeBuiltin(Builtins::TO_OBJECT, CALL_FUNCTION); |
| 3974 __ LeaveInternalFrame(); | 3974 __ LeaveInternalFrame(); |
| 3975 __ mov(Operand(esp, (argc_ + 1) * kPointerSize), eax); | 3975 __ mov(Operand(esp, (argc_ + 1) * kPointerSize), eax); |
| 3976 | 3976 |
| (...skipping 2214 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6191 __ Drop(1); | 6191 __ Drop(1); |
| 6192 __ ret(2 * kPointerSize); | 6192 __ ret(2 * kPointerSize); |
| 6193 } | 6193 } |
| 6194 | 6194 |
| 6195 | 6195 |
| 6196 #undef __ | 6196 #undef __ |
| 6197 | 6197 |
| 6198 } } // namespace v8::internal | 6198 } } // namespace v8::internal |
| 6199 | 6199 |
| 6200 #endif // V8_TARGET_ARCH_IA32 | 6200 #endif // V8_TARGET_ARCH_IA32 |
| OLD | NEW |