OLD | NEW |
1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 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 3101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3112 __ bind(&slowcase); | 3112 __ bind(&slowcase); |
3113 __ TailCallRuntime(Runtime::kRegExpConstructResult, 3, 1); | 3113 __ TailCallRuntime(Runtime::kRegExpConstructResult, 3, 1); |
3114 } | 3114 } |
3115 | 3115 |
3116 | 3116 |
3117 void NumberToStringStub::GenerateLookupNumberStringCache(MacroAssembler* masm, | 3117 void NumberToStringStub::GenerateLookupNumberStringCache(MacroAssembler* masm, |
3118 Register object, | 3118 Register object, |
3119 Register result, | 3119 Register result, |
3120 Register scratch1, | 3120 Register scratch1, |
3121 Register scratch2, | 3121 Register scratch2, |
3122 bool object_is_smi, | |
3123 Label* not_found) { | 3122 Label* not_found) { |
3124 // Use of registers. Register result is used as a temporary. | 3123 // Use of registers. Register result is used as a temporary. |
3125 Register number_string_cache = result; | 3124 Register number_string_cache = result; |
3126 Register mask = scratch1; | 3125 Register mask = scratch1; |
3127 Register scratch = scratch2; | 3126 Register scratch = scratch2; |
3128 | 3127 |
3129 // Load the number string cache. | 3128 // Load the number string cache. |
3130 __ LoadRoot(number_string_cache, Heap::kNumberStringCacheRootIndex); | 3129 __ LoadRoot(number_string_cache, Heap::kNumberStringCacheRootIndex); |
3131 | 3130 |
3132 // Make the hash mask from the length of the number string cache. It | 3131 // Make the hash mask from the length of the number string cache. It |
3133 // contains two elements (number and string) for each cache entry. | 3132 // contains two elements (number and string) for each cache entry. |
3134 __ SmiToInteger32( | 3133 __ SmiToInteger32( |
3135 mask, FieldOperand(number_string_cache, FixedArray::kLengthOffset)); | 3134 mask, FieldOperand(number_string_cache, FixedArray::kLengthOffset)); |
3136 __ shrl(mask, Immediate(1)); | 3135 __ shrl(mask, Immediate(1)); |
3137 __ subq(mask, Immediate(1)); // Make mask. | 3136 __ subq(mask, Immediate(1)); // Make mask. |
3138 | 3137 |
3139 // Calculate the entry in the number string cache. The hash value in the | 3138 // Calculate the entry in the number string cache. The hash value in the |
3140 // number string cache for smis is just the smi value, and the hash for | 3139 // number string cache for smis is just the smi value, and the hash for |
3141 // doubles is the xor of the upper and lower words. See | 3140 // doubles is the xor of the upper and lower words. See |
3142 // Heap::GetNumberStringCache. | 3141 // Heap::GetNumberStringCache. |
3143 Label is_smi; | 3142 Label is_smi; |
3144 Label load_result_from_cache; | 3143 Label load_result_from_cache; |
3145 Factory* factory = masm->isolate()->factory(); | 3144 Factory* factory = masm->isolate()->factory(); |
3146 if (!object_is_smi) { | 3145 __ JumpIfSmi(object, &is_smi); |
3147 __ JumpIfSmi(object, &is_smi); | 3146 __ CheckMap(object, |
3148 __ CheckMap(object, | 3147 factory->heap_number_map(), |
3149 factory->heap_number_map(), | 3148 not_found, |
3150 not_found, | 3149 DONT_DO_SMI_CHECK); |
3151 DONT_DO_SMI_CHECK); | |
3152 | 3150 |
3153 STATIC_ASSERT(8 == kDoubleSize); | 3151 STATIC_ASSERT(8 == kDoubleSize); |
3154 __ movl(scratch, FieldOperand(object, HeapNumber::kValueOffset + 4)); | 3152 __ movl(scratch, FieldOperand(object, HeapNumber::kValueOffset + 4)); |
3155 __ xor_(scratch, FieldOperand(object, HeapNumber::kValueOffset)); | 3153 __ xor_(scratch, FieldOperand(object, HeapNumber::kValueOffset)); |
3156 GenerateConvertHashCodeToIndex(masm, scratch, mask); | 3154 GenerateConvertHashCodeToIndex(masm, scratch, mask); |
3157 | 3155 |
3158 Register index = scratch; | 3156 Register index = scratch; |
3159 Register probe = mask; | 3157 Register probe = mask; |
3160 __ movq(probe, | 3158 __ movq(probe, |
3161 FieldOperand(number_string_cache, | 3159 FieldOperand(number_string_cache, |
3162 index, | 3160 index, |
3163 times_1, | 3161 times_1, |
3164 FixedArray::kHeaderSize)); | 3162 FixedArray::kHeaderSize)); |
3165 __ JumpIfSmi(probe, not_found); | 3163 __ JumpIfSmi(probe, not_found); |
3166 __ movsd(xmm0, FieldOperand(object, HeapNumber::kValueOffset)); | 3164 __ movsd(xmm0, FieldOperand(object, HeapNumber::kValueOffset)); |
3167 __ movsd(xmm1, FieldOperand(probe, HeapNumber::kValueOffset)); | 3165 __ movsd(xmm1, FieldOperand(probe, HeapNumber::kValueOffset)); |
3168 __ ucomisd(xmm0, xmm1); | 3166 __ ucomisd(xmm0, xmm1); |
3169 __ j(parity_even, not_found); // Bail out if NaN is involved. | 3167 __ j(parity_even, not_found); // Bail out if NaN is involved. |
3170 __ j(not_equal, not_found); // The cache did not contain this value. | 3168 __ j(not_equal, not_found); // The cache did not contain this value. |
3171 __ jmp(&load_result_from_cache); | 3169 __ jmp(&load_result_from_cache); |
3172 } | |
3173 | 3170 |
3174 __ bind(&is_smi); | 3171 __ bind(&is_smi); |
3175 __ SmiToInteger32(scratch, object); | 3172 __ SmiToInteger32(scratch, object); |
3176 GenerateConvertHashCodeToIndex(masm, scratch, mask); | 3173 GenerateConvertHashCodeToIndex(masm, scratch, mask); |
3177 | 3174 |
3178 Register index = scratch; | |
3179 // Check if the entry is the smi we are looking for. | 3175 // Check if the entry is the smi we are looking for. |
3180 __ cmpq(object, | 3176 __ cmpq(object, |
3181 FieldOperand(number_string_cache, | 3177 FieldOperand(number_string_cache, |
3182 index, | 3178 index, |
3183 times_1, | 3179 times_1, |
3184 FixedArray::kHeaderSize)); | 3180 FixedArray::kHeaderSize)); |
3185 __ j(not_equal, not_found); | 3181 __ j(not_equal, not_found); |
3186 | 3182 |
3187 // Get the result from the cache. | 3183 // Get the result from the cache. |
3188 __ bind(&load_result_from_cache); | 3184 __ bind(&load_result_from_cache); |
(...skipping 18 matching lines...) Expand all Loading... |
3207 __ shl(hash, Immediate(kPointerSizeLog2 + 1)); | 3203 __ shl(hash, Immediate(kPointerSizeLog2 + 1)); |
3208 } | 3204 } |
3209 | 3205 |
3210 | 3206 |
3211 void NumberToStringStub::Generate(MacroAssembler* masm) { | 3207 void NumberToStringStub::Generate(MacroAssembler* masm) { |
3212 Label runtime; | 3208 Label runtime; |
3213 | 3209 |
3214 __ movq(rbx, Operand(rsp, kPointerSize)); | 3210 __ movq(rbx, Operand(rsp, kPointerSize)); |
3215 | 3211 |
3216 // Generate code to lookup number in the number string cache. | 3212 // Generate code to lookup number in the number string cache. |
3217 GenerateLookupNumberStringCache(masm, rbx, rax, r8, r9, false, &runtime); | 3213 GenerateLookupNumberStringCache(masm, rbx, rax, r8, r9, &runtime); |
3218 __ ret(1 * kPointerSize); | 3214 __ ret(1 * kPointerSize); |
3219 | 3215 |
3220 __ bind(&runtime); | 3216 __ bind(&runtime); |
3221 // Handle number to string in the runtime system if not found in the cache. | 3217 // Handle number to string in the runtime system if not found in the cache. |
3222 __ TailCallRuntime(Runtime::kNumberToStringSkipCache, 1, 1); | 3218 __ TailCallRuntime(Runtime::kNumberToStringSkipCache, 1, 1); |
3223 } | 3219 } |
3224 | 3220 |
3225 | 3221 |
3226 static int NegativeComparisonResult(Condition cc) { | 3222 static int NegativeComparisonResult(Condition cc) { |
3227 ASSERT(cc != equal); | 3223 ASSERT(cc != equal); |
(...skipping 1632 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4860 | 4856 |
4861 // Check the number to string cache. | 4857 // Check the number to string cache. |
4862 Label not_cached; | 4858 Label not_cached; |
4863 __ bind(¬_string); | 4859 __ bind(¬_string); |
4864 // Puts the cached result into scratch1. | 4860 // Puts the cached result into scratch1. |
4865 NumberToStringStub::GenerateLookupNumberStringCache(masm, | 4861 NumberToStringStub::GenerateLookupNumberStringCache(masm, |
4866 arg, | 4862 arg, |
4867 scratch1, | 4863 scratch1, |
4868 scratch2, | 4864 scratch2, |
4869 scratch3, | 4865 scratch3, |
4870 false, | |
4871 ¬_cached); | 4866 ¬_cached); |
4872 __ movq(arg, scratch1); | 4867 __ movq(arg, scratch1); |
4873 __ movq(Operand(rsp, stack_offset), arg); | 4868 __ movq(Operand(rsp, stack_offset), arg); |
4874 __ jmp(&done); | 4869 __ jmp(&done); |
4875 | 4870 |
4876 // Check if the argument is a safe string wrapper. | 4871 // Check if the argument is a safe string wrapper. |
4877 __ bind(¬_cached); | 4872 __ bind(¬_cached); |
4878 __ JumpIfSmi(arg, slow); | 4873 __ JumpIfSmi(arg, slow); |
4879 __ CmpObjectType(arg, JS_VALUE_TYPE, scratch1); // map -> scratch1. | 4874 __ CmpObjectType(arg, JS_VALUE_TYPE, scratch1); // map -> scratch1. |
4880 __ j(not_equal, slow); | 4875 __ j(not_equal, slow); |
(...skipping 1957 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6838 __ bind(&fast_elements_case); | 6833 __ bind(&fast_elements_case); |
6839 GenerateCase(masm, FAST_ELEMENTS); | 6834 GenerateCase(masm, FAST_ELEMENTS); |
6840 } | 6835 } |
6841 | 6836 |
6842 | 6837 |
6843 #undef __ | 6838 #undef __ |
6844 | 6839 |
6845 } } // namespace v8::internal | 6840 } } // namespace v8::internal |
6846 | 6841 |
6847 #endif // V8_TARGET_ARCH_X64 | 6842 #endif // V8_TARGET_ARCH_X64 |
OLD | NEW |