OLD | NEW |
1 // Copyright 2016 the V8 project authors. All rights reserved. | 1 // Copyright 2016 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/code-stub-assembler.h" | 5 #include "src/code-stub-assembler.h" |
6 #include "src/code-factory.h" | 6 #include "src/code-factory.h" |
7 #include "src/frames-inl.h" | 7 #include "src/frames-inl.h" |
8 #include "src/frames.h" | 8 #include "src/frames.h" |
9 #include "src/ic/handler-configuration.h" | 9 #include "src/ic/handler-configuration.h" |
10 #include "src/ic/stub-cache.h" | 10 #include "src/ic/stub-cache.h" |
(...skipping 2813 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2824 Bind(&runtime); | 2824 Bind(&runtime); |
2825 { | 2825 { |
2826 var_result.Bind(CallRuntime(Runtime::kStringToNumber, context, input)); | 2826 var_result.Bind(CallRuntime(Runtime::kStringToNumber, context, input)); |
2827 Goto(&end); | 2827 Goto(&end); |
2828 } | 2828 } |
2829 | 2829 |
2830 Bind(&end); | 2830 Bind(&end); |
2831 return var_result.value(); | 2831 return var_result.value(); |
2832 } | 2832 } |
2833 | 2833 |
| 2834 Node* CodeStubAssembler::NumberToString(compiler::Node* context, |
| 2835 compiler::Node* argument) { |
| 2836 Variable result(this, MachineRepresentation::kTagged); |
| 2837 Label runtime(this, Label::kDeferred); |
| 2838 Label smi(this); |
| 2839 Label done(this, &result); |
| 2840 |
| 2841 // Load the number string cache. |
| 2842 Node* number_string_cache = LoadRoot(Heap::kNumberStringCacheRootIndex); |
| 2843 |
| 2844 // Make the hash mask from the length of the number string cache. It |
| 2845 // contains two elements (number and string) for each cache entry. |
| 2846 Node* mask = LoadFixedArrayBaseLength(number_string_cache); |
| 2847 Node* one = IntPtrConstant(1); |
| 2848 mask = IntPtrSub(mask, one); |
| 2849 |
| 2850 GotoIf(WordIsSmi(argument), &smi); |
| 2851 |
| 2852 // Argument isn't smi, check to see if it's a heap-number. |
| 2853 Node* map = LoadMap(argument); |
| 2854 GotoUnless(WordEqual(map, HeapNumberMapConstant()), &runtime); |
| 2855 |
| 2856 // Make a hash from the two 32-bit values of the double. |
| 2857 Node* low = |
| 2858 LoadObjectField(argument, HeapNumber::kValueOffset, MachineType::Int32()); |
| 2859 Node* high = LoadObjectField(argument, HeapNumber::kValueOffset + kIntSize, |
| 2860 MachineType::Int32()); |
| 2861 Node* hash = Word32Xor(low, high); |
| 2862 if (Is64()) hash = ChangeInt32ToInt64(hash); |
| 2863 hash = WordShl(hash, one); |
| 2864 Node* index = WordAnd(hash, SmiToWord(mask)); |
| 2865 |
| 2866 // Cache entry's key must be a heap number |
| 2867 Node* number_key = |
| 2868 LoadFixedArrayElement(number_string_cache, index, 0, INTPTR_PARAMETERS); |
| 2869 GotoIf(WordIsSmi(number_key), &runtime); |
| 2870 map = LoadMap(number_key); |
| 2871 GotoUnless(WordEqual(map, HeapNumberMapConstant()), &runtime); |
| 2872 |
| 2873 // Cache entry's key must match the heap number value we're looking for. |
| 2874 Node* low_compare = LoadObjectField(number_key, HeapNumber::kValueOffset, |
| 2875 MachineType::Int32()); |
| 2876 Node* high_compare = LoadObjectField( |
| 2877 number_key, HeapNumber::kValueOffset + kIntSize, MachineType::Int32()); |
| 2878 GotoUnless(WordEqual(low, low_compare), &runtime); |
| 2879 GotoUnless(WordEqual(high, high_compare), &runtime); |
| 2880 |
| 2881 // Heap number match, return value fro cache entry. |
| 2882 IncrementCounter(isolate()->counters()->number_to_string_native(), 1); |
| 2883 result.Bind(LoadFixedArrayElement(number_string_cache, index, kPointerSize, |
| 2884 INTPTR_PARAMETERS)); |
| 2885 Goto(&done); |
| 2886 |
| 2887 Bind(&runtime); |
| 2888 { |
| 2889 // No cache entry, go to the runtime. |
| 2890 result.Bind(CallRuntime(Runtime::kNumberToString, context, argument)); |
| 2891 } |
| 2892 Goto(&done); |
| 2893 |
| 2894 Bind(&smi); |
| 2895 { |
| 2896 // Load the smi key, make sure it matches the smi we're looking for. |
| 2897 Node* smi_index = WordAnd(WordShl(argument, one), mask); |
| 2898 Node* smi_key = LoadFixedArrayElement(number_string_cache, smi_index, 0, |
| 2899 SMI_PARAMETERS); |
| 2900 GotoIf(WordNotEqual(smi_key, argument), &runtime); |
| 2901 |
| 2902 // Smi match, return value from cache entry. |
| 2903 IncrementCounter(isolate()->counters()->number_to_string_native(), 1); |
| 2904 result.Bind(LoadFixedArrayElement(number_string_cache, smi_index, |
| 2905 kPointerSize, SMI_PARAMETERS)); |
| 2906 Goto(&done); |
| 2907 } |
| 2908 |
| 2909 Bind(&done); |
| 2910 return result.value(); |
| 2911 } |
| 2912 |
2834 Node* CodeStubAssembler::ToName(Node* context, Node* value) { | 2913 Node* CodeStubAssembler::ToName(Node* context, Node* value) { |
2835 typedef CodeStubAssembler::Label Label; | 2914 typedef CodeStubAssembler::Label Label; |
2836 typedef CodeStubAssembler::Variable Variable; | 2915 typedef CodeStubAssembler::Variable Variable; |
2837 | 2916 |
2838 Label end(this); | 2917 Label end(this); |
2839 Variable var_result(this, MachineRepresentation::kTagged); | 2918 Variable var_result(this, MachineRepresentation::kTagged); |
2840 | 2919 |
2841 Label is_number(this); | 2920 Label is_number(this); |
2842 GotoIf(WordIsSmi(value), &is_number); | 2921 GotoIf(WordIsSmi(value), &is_number); |
2843 | 2922 |
(...skipping 4295 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7139 result.Bind(CallRuntime(Runtime::kInstanceOf, context, object, callable)); | 7218 result.Bind(CallRuntime(Runtime::kInstanceOf, context, object, callable)); |
7140 Goto(&end); | 7219 Goto(&end); |
7141 } | 7220 } |
7142 | 7221 |
7143 Bind(&end); | 7222 Bind(&end); |
7144 return result.value(); | 7223 return result.value(); |
7145 } | 7224 } |
7146 | 7225 |
7147 } // namespace internal | 7226 } // namespace internal |
7148 } // namespace v8 | 7227 } // namespace v8 |
OLD | NEW |