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 |