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 2926 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2937 mask, FieldOperand(number_string_cache, FixedArray::kLengthOffset)); | 2937 mask, FieldOperand(number_string_cache, FixedArray::kLengthOffset)); |
2938 __ shrl(mask, Immediate(1)); | 2938 __ shrl(mask, Immediate(1)); |
2939 __ subq(mask, Immediate(1)); // Make mask. | 2939 __ subq(mask, Immediate(1)); // Make mask. |
2940 | 2940 |
2941 // Calculate the entry in the number string cache. The hash value in the | 2941 // Calculate the entry in the number string cache. The hash value in the |
2942 // number string cache for smis is just the smi value, and the hash for | 2942 // number string cache for smis is just the smi value, and the hash for |
2943 // doubles is the xor of the upper and lower words. See | 2943 // doubles is the xor of the upper and lower words. See |
2944 // Heap::GetNumberStringCache. | 2944 // Heap::GetNumberStringCache. |
2945 Label is_smi; | 2945 Label is_smi; |
2946 Label load_result_from_cache; | 2946 Label load_result_from_cache; |
| 2947 Factory* factory = masm->isolate()->factory(); |
2947 if (!object_is_smi) { | 2948 if (!object_is_smi) { |
2948 __ JumpIfSmi(object, &is_smi); | 2949 __ JumpIfSmi(object, &is_smi); |
2949 __ CheckMap(object, FACTORY->heap_number_map(), not_found, true); | 2950 __ CheckMap(object, factory->heap_number_map(), not_found, true); |
2950 | 2951 |
2951 STATIC_ASSERT(8 == kDoubleSize); | 2952 STATIC_ASSERT(8 == kDoubleSize); |
2952 __ movl(scratch, FieldOperand(object, HeapNumber::kValueOffset + 4)); | 2953 __ movl(scratch, FieldOperand(object, HeapNumber::kValueOffset + 4)); |
2953 __ xor_(scratch, FieldOperand(object, HeapNumber::kValueOffset)); | 2954 __ xor_(scratch, FieldOperand(object, HeapNumber::kValueOffset)); |
2954 GenerateConvertHashCodeToIndex(masm, scratch, mask); | 2955 GenerateConvertHashCodeToIndex(masm, scratch, mask); |
2955 | 2956 |
2956 Register index = scratch; | 2957 Register index = scratch; |
2957 Register probe = mask; | 2958 Register probe = mask; |
2958 __ movq(probe, | 2959 __ movq(probe, |
2959 FieldOperand(number_string_cache, | 2960 FieldOperand(number_string_cache, |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3028 ASSERT((cc == less) || (cc == less_equal) | 3029 ASSERT((cc == less) || (cc == less_equal) |
3029 || (cc == greater) || (cc == greater_equal)); | 3030 || (cc == greater) || (cc == greater_equal)); |
3030 return (cc == greater || cc == greater_equal) ? LESS : GREATER; | 3031 return (cc == greater || cc == greater_equal) ? LESS : GREATER; |
3031 } | 3032 } |
3032 | 3033 |
3033 | 3034 |
3034 void CompareStub::Generate(MacroAssembler* masm) { | 3035 void CompareStub::Generate(MacroAssembler* masm) { |
3035 ASSERT(lhs_.is(no_reg) && rhs_.is(no_reg)); | 3036 ASSERT(lhs_.is(no_reg) && rhs_.is(no_reg)); |
3036 | 3037 |
3037 Label check_unequal_objects, done; | 3038 Label check_unequal_objects, done; |
| 3039 Factory* factory = masm->isolate()->factory(); |
3038 | 3040 |
3039 // Compare two smis if required. | 3041 // Compare two smis if required. |
3040 if (include_smi_compare_) { | 3042 if (include_smi_compare_) { |
3041 Label non_smi, smi_done; | 3043 Label non_smi, smi_done; |
3042 __ JumpIfNotBothSmi(rax, rdx, &non_smi); | 3044 __ JumpIfNotBothSmi(rax, rdx, &non_smi); |
3043 __ subq(rdx, rax); | 3045 __ subq(rdx, rax); |
3044 __ j(no_overflow, &smi_done); | 3046 __ j(no_overflow, &smi_done); |
3045 __ not_(rdx); // Correct sign in case of overflow. rdx cannot be 0 here. | 3047 __ not_(rdx); // Correct sign in case of overflow. rdx cannot be 0 here. |
3046 __ bind(&smi_done); | 3048 __ bind(&smi_done); |
3047 __ movq(rax, rdx); | 3049 __ movq(rax, rdx); |
(...skipping 27 matching lines...) Expand all Loading... |
3075 __ Set(rax, NegativeComparisonResult(cc_)); | 3077 __ Set(rax, NegativeComparisonResult(cc_)); |
3076 __ ret(0); | 3078 __ ret(0); |
3077 __ bind(&check_for_nan); | 3079 __ bind(&check_for_nan); |
3078 } | 3080 } |
3079 | 3081 |
3080 // Test for NaN. Sadly, we can't just compare to FACTORY->nan_value(), | 3082 // Test for NaN. Sadly, we can't just compare to FACTORY->nan_value(), |
3081 // so we do the second best thing - test it ourselves. | 3083 // so we do the second best thing - test it ourselves. |
3082 // Note: if cc_ != equal, never_nan_nan_ is not used. | 3084 // Note: if cc_ != equal, never_nan_nan_ is not used. |
3083 // We cannot set rax to EQUAL until just before return because | 3085 // We cannot set rax to EQUAL until just before return because |
3084 // rax must be unchanged on jump to not_identical. | 3086 // rax must be unchanged on jump to not_identical. |
3085 | |
3086 if (never_nan_nan_ && (cc_ == equal)) { | 3087 if (never_nan_nan_ && (cc_ == equal)) { |
3087 __ Set(rax, EQUAL); | 3088 __ Set(rax, EQUAL); |
3088 __ ret(0); | 3089 __ ret(0); |
3089 } else { | 3090 } else { |
3090 NearLabel heap_number; | 3091 NearLabel heap_number; |
3091 // If it's not a heap number, then return equal for (in)equality operator. | 3092 // If it's not a heap number, then return equal for (in)equality operator. |
3092 __ Cmp(FieldOperand(rdx, HeapObject::kMapOffset), | 3093 __ Cmp(FieldOperand(rdx, HeapObject::kMapOffset), |
3093 FACTORY->heap_number_map()); | 3094 factory->heap_number_map()); |
3094 __ j(equal, &heap_number); | 3095 __ j(equal, &heap_number); |
3095 if (cc_ != equal) { | 3096 if (cc_ != equal) { |
3096 // Call runtime on identical JSObjects. Otherwise return equal. | 3097 // Call runtime on identical JSObjects. Otherwise return equal. |
3097 __ CmpObjectType(rax, FIRST_JS_OBJECT_TYPE, rcx); | 3098 __ CmpObjectType(rax, FIRST_JS_OBJECT_TYPE, rcx); |
3098 __ j(above_equal, ¬_identical); | 3099 __ j(above_equal, ¬_identical); |
3099 } | 3100 } |
3100 __ Set(rax, EQUAL); | 3101 __ Set(rax, EQUAL); |
3101 __ ret(0); | 3102 __ ret(0); |
3102 | 3103 |
3103 __ bind(&heap_number); | 3104 __ bind(&heap_number); |
(...skipping 24 matching lines...) Expand all Loading... |
3128 // slow-case code. | 3129 // slow-case code. |
3129 if (strict_) { | 3130 if (strict_) { |
3130 // If either is a Smi (we know that not both are), then they can only | 3131 // If either is a Smi (we know that not both are), then they can only |
3131 // be equal if the other is a HeapNumber. If so, use the slow case. | 3132 // be equal if the other is a HeapNumber. If so, use the slow case. |
3132 { | 3133 { |
3133 Label not_smis; | 3134 Label not_smis; |
3134 __ SelectNonSmi(rbx, rax, rdx, ¬_smis); | 3135 __ SelectNonSmi(rbx, rax, rdx, ¬_smis); |
3135 | 3136 |
3136 // Check if the non-smi operand is a heap number. | 3137 // Check if the non-smi operand is a heap number. |
3137 __ Cmp(FieldOperand(rbx, HeapObject::kMapOffset), | 3138 __ Cmp(FieldOperand(rbx, HeapObject::kMapOffset), |
3138 FACTORY->heap_number_map()); | 3139 factory->heap_number_map()); |
3139 // If heap number, handle it in the slow case. | 3140 // If heap number, handle it in the slow case. |
3140 __ j(equal, &slow); | 3141 __ j(equal, &slow); |
3141 // Return non-equal. ebx (the lower half of rbx) is not zero. | 3142 // Return non-equal. ebx (the lower half of rbx) is not zero. |
3142 __ movq(rax, rbx); | 3143 __ movq(rax, rbx); |
3143 __ ret(0); | 3144 __ ret(0); |
3144 | 3145 |
3145 __ bind(¬_smis); | 3146 __ bind(¬_smis); |
3146 } | 3147 } |
3147 | 3148 |
3148 // If either operand is a JSObject or an oddball value, then they are not | 3149 // If either operand is a JSObject or an oddball value, then they are not |
(...skipping 910 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4059 __ bind(&got_char_code); | 4060 __ bind(&got_char_code); |
4060 __ Integer32ToSmi(result_, result_); | 4061 __ Integer32ToSmi(result_, result_); |
4061 __ bind(&exit_); | 4062 __ bind(&exit_); |
4062 } | 4063 } |
4063 | 4064 |
4064 | 4065 |
4065 void StringCharCodeAtGenerator::GenerateSlow( | 4066 void StringCharCodeAtGenerator::GenerateSlow( |
4066 MacroAssembler* masm, const RuntimeCallHelper& call_helper) { | 4067 MacroAssembler* masm, const RuntimeCallHelper& call_helper) { |
4067 __ Abort("Unexpected fallthrough to CharCodeAt slow case"); | 4068 __ Abort("Unexpected fallthrough to CharCodeAt slow case"); |
4068 | 4069 |
| 4070 Factory* factory = masm->isolate()->factory(); |
4069 // Index is not a smi. | 4071 // Index is not a smi. |
4070 __ bind(&index_not_smi_); | 4072 __ bind(&index_not_smi_); |
4071 // If index is a heap number, try converting it to an integer. | 4073 // If index is a heap number, try converting it to an integer. |
4072 __ CheckMap(index_, FACTORY->heap_number_map(), index_not_number_, true); | 4074 __ CheckMap(index_, factory->heap_number_map(), index_not_number_, true); |
4073 call_helper.BeforeCall(masm); | 4075 call_helper.BeforeCall(masm); |
4074 __ push(object_); | 4076 __ push(object_); |
4075 __ push(index_); | 4077 __ push(index_); |
4076 __ push(index_); // Consumed by runtime conversion function. | 4078 __ push(index_); // Consumed by runtime conversion function. |
4077 if (index_flags_ == STRING_INDEX_IS_NUMBER) { | 4079 if (index_flags_ == STRING_INDEX_IS_NUMBER) { |
4078 __ CallRuntime(Runtime::kNumberToIntegerMapMinusZero, 1); | 4080 __ CallRuntime(Runtime::kNumberToIntegerMapMinusZero, 1); |
4079 } else { | 4081 } else { |
4080 ASSERT(index_flags_ == STRING_INDEX_IS_ARRAY_INDEX); | 4082 ASSERT(index_flags_ == STRING_INDEX_IS_ARRAY_INDEX); |
4081 // NumberToSmi discards numbers that are not exact integers. | 4083 // NumberToSmi discards numbers that are not exact integers. |
4082 __ CallRuntime(Runtime::kNumberToSmi, 1); | 4084 __ CallRuntime(Runtime::kNumberToSmi, 1); |
(...skipping 1042 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5125 // Do a tail call to the rewritten stub. | 5127 // Do a tail call to the rewritten stub. |
5126 __ jmp(rdi); | 5128 __ jmp(rdi); |
5127 } | 5129 } |
5128 | 5130 |
5129 | 5131 |
5130 #undef __ | 5132 #undef __ |
5131 | 5133 |
5132 } } // namespace v8::internal | 5134 } } // namespace v8::internal |
5133 | 5135 |
5134 #endif // V8_TARGET_ARCH_X64 | 5136 #endif // V8_TARGET_ARCH_X64 |
OLD | NEW |