| 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 |