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 2891 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2902 __ jmp(&loop); | 2902 __ jmp(&loop); |
2903 | 2903 |
2904 __ bind(&done); | 2904 __ bind(&done); |
2905 __ ret(3 * kPointerSize); | 2905 __ ret(3 * kPointerSize); |
2906 | 2906 |
2907 __ bind(&slowcase); | 2907 __ bind(&slowcase); |
2908 __ TailCallRuntime(Runtime::kRegExpConstructResult, 3, 1); | 2908 __ TailCallRuntime(Runtime::kRegExpConstructResult, 3, 1); |
2909 } | 2909 } |
2910 | 2910 |
2911 | 2911 |
2912 void NumberToStringStub::GenerateLookupNumberStringCache(MacroAssembler* masm, | |
2913 Register object, | |
2914 Register result, | |
2915 Register scratch1, | |
2916 Register scratch2, | |
2917 Label* not_found) { | |
2918 // Use of registers. Register result is used as a temporary. | |
2919 Register number_string_cache = result; | |
2920 Register mask = scratch1; | |
2921 Register scratch = scratch2; | |
2922 | |
2923 // Load the number string cache. | |
2924 __ LoadRoot(number_string_cache, Heap::kNumberStringCacheRootIndex); | |
2925 | |
2926 // Make the hash mask from the length of the number string cache. It | |
2927 // contains two elements (number and string) for each cache entry. | |
2928 __ SmiToInteger32( | |
2929 mask, FieldOperand(number_string_cache, FixedArray::kLengthOffset)); | |
2930 __ shrl(mask, Immediate(1)); | |
2931 __ subq(mask, Immediate(1)); // Make mask. | |
2932 | |
2933 // Calculate the entry in the number string cache. The hash value in the | |
2934 // number string cache for smis is just the smi value, and the hash for | |
2935 // doubles is the xor of the upper and lower words. See | |
2936 // Heap::GetNumberStringCache. | |
2937 Label is_smi; | |
2938 Label load_result_from_cache; | |
2939 Factory* factory = masm->isolate()->factory(); | |
2940 __ JumpIfSmi(object, &is_smi); | |
2941 __ CheckMap(object, | |
2942 factory->heap_number_map(), | |
2943 not_found, | |
2944 DONT_DO_SMI_CHECK); | |
2945 | |
2946 STATIC_ASSERT(8 == kDoubleSize); | |
2947 __ movl(scratch, FieldOperand(object, HeapNumber::kValueOffset + 4)); | |
2948 __ xor_(scratch, FieldOperand(object, HeapNumber::kValueOffset)); | |
2949 GenerateConvertHashCodeToIndex(masm, scratch, mask); | |
2950 | |
2951 Register index = scratch; | |
2952 Register probe = mask; | |
2953 __ movq(probe, | |
2954 FieldOperand(number_string_cache, | |
2955 index, | |
2956 times_1, | |
2957 FixedArray::kHeaderSize)); | |
2958 __ JumpIfSmi(probe, not_found); | |
2959 __ movsd(xmm0, FieldOperand(object, HeapNumber::kValueOffset)); | |
2960 __ movsd(xmm1, FieldOperand(probe, HeapNumber::kValueOffset)); | |
2961 __ ucomisd(xmm0, xmm1); | |
2962 __ j(parity_even, not_found); // Bail out if NaN is involved. | |
2963 __ j(not_equal, not_found); // The cache did not contain this value. | |
2964 __ jmp(&load_result_from_cache); | |
2965 | |
2966 __ bind(&is_smi); | |
2967 __ SmiToInteger32(scratch, object); | |
2968 GenerateConvertHashCodeToIndex(masm, scratch, mask); | |
2969 | |
2970 // Check if the entry is the smi we are looking for. | |
2971 __ cmpq(object, | |
2972 FieldOperand(number_string_cache, | |
2973 index, | |
2974 times_1, | |
2975 FixedArray::kHeaderSize)); | |
2976 __ j(not_equal, not_found); | |
2977 | |
2978 // Get the result from the cache. | |
2979 __ bind(&load_result_from_cache); | |
2980 __ movq(result, | |
2981 FieldOperand(number_string_cache, | |
2982 index, | |
2983 times_1, | |
2984 FixedArray::kHeaderSize + kPointerSize)); | |
2985 Counters* counters = masm->isolate()->counters(); | |
2986 __ IncrementCounter(counters->number_to_string_native(), 1); | |
2987 } | |
2988 | |
2989 | |
2990 void NumberToStringStub::GenerateConvertHashCodeToIndex(MacroAssembler* masm, | |
2991 Register hash, | |
2992 Register mask) { | |
2993 __ and_(hash, mask); | |
2994 // Each entry in string cache consists of two pointer sized fields, | |
2995 // but times_twice_pointer_size (multiplication by 16) scale factor | |
2996 // is not supported by addrmode on x64 platform. | |
2997 // So we have to premultiply entry index before lookup. | |
2998 __ shl(hash, Immediate(kPointerSizeLog2 + 1)); | |
2999 } | |
3000 | |
3001 | |
3002 void NumberToStringStub::Generate(MacroAssembler* masm) { | 2912 void NumberToStringStub::Generate(MacroAssembler* masm) { |
3003 Label runtime; | 2913 Label runtime; |
3004 | 2914 |
3005 StackArgumentsAccessor args(rsp, 1, ARGUMENTS_DONT_CONTAIN_RECEIVER); | 2915 StackArgumentsAccessor args(rsp, 1, ARGUMENTS_DONT_CONTAIN_RECEIVER); |
3006 __ movq(rbx, args.GetArgumentOperand(0)); | 2916 __ movq(rbx, args.GetArgumentOperand(0)); |
3007 | 2917 |
3008 // Generate code to lookup number in the number string cache. | 2918 // Generate code to lookup number in the number string cache. |
3009 GenerateLookupNumberStringCache(masm, rbx, rax, r8, r9, &runtime); | 2919 __ LookupNumberStringCache(rbx, rax, r8, r9, &runtime); |
3010 __ ret(1 * kPointerSize); | 2920 __ ret(1 * kPointerSize); |
3011 | 2921 |
3012 __ bind(&runtime); | 2922 __ bind(&runtime); |
3013 // Handle number to string in the runtime system if not found in the cache. | 2923 // Handle number to string in the runtime system if not found in the cache. |
3014 __ TailCallRuntime(Runtime::kNumberToStringSkipCache, 1, 1); | 2924 __ TailCallRuntime(Runtime::kNumberToStringSkipCache, 1, 1); |
3015 } | 2925 } |
3016 | 2926 |
3017 | 2927 |
3018 static int NegativeComparisonResult(Condition cc) { | 2928 static int NegativeComparisonResult(Condition cc) { |
3019 ASSERT(cc != equal); | 2929 ASSERT(cc != equal); |
(...skipping 1619 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4639 Label* slow) { | 4549 Label* slow) { |
4640 // First check if the argument is already a string. | 4550 // First check if the argument is already a string. |
4641 Label not_string, done; | 4551 Label not_string, done; |
4642 __ JumpIfSmi(arg, ¬_string); | 4552 __ JumpIfSmi(arg, ¬_string); |
4643 __ CmpObjectType(arg, FIRST_NONSTRING_TYPE, scratch1); | 4553 __ CmpObjectType(arg, FIRST_NONSTRING_TYPE, scratch1); |
4644 __ j(below, &done); | 4554 __ j(below, &done); |
4645 | 4555 |
4646 // Check the number to string cache. | 4556 // Check the number to string cache. |
4647 __ bind(¬_string); | 4557 __ bind(¬_string); |
4648 // Puts the cached result into scratch1. | 4558 // Puts the cached result into scratch1. |
4649 NumberToStringStub::GenerateLookupNumberStringCache(masm, | 4559 __ LookupNumberStringCache(arg, scratch1, scratch2, scratch3, slow); |
4650 arg, | |
4651 scratch1, | |
4652 scratch2, | |
4653 scratch3, | |
4654 slow); | |
4655 __ movq(arg, scratch1); | 4560 __ movq(arg, scratch1); |
4656 __ movq(Operand(rsp, stack_offset), arg); | 4561 __ movq(Operand(rsp, stack_offset), arg); |
4657 __ bind(&done); | 4562 __ bind(&done); |
4658 } | 4563 } |
4659 | 4564 |
4660 | 4565 |
4661 void StringHelper::GenerateCopyCharacters(MacroAssembler* masm, | 4566 void StringHelper::GenerateCopyCharacters(MacroAssembler* masm, |
4662 Register dest, | 4567 Register dest, |
4663 Register src, | 4568 Register src, |
4664 Register count, | 4569 Register count, |
(...skipping 1976 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6641 __ bind(&fast_elements_case); | 6546 __ bind(&fast_elements_case); |
6642 GenerateCase(masm, FAST_ELEMENTS); | 6547 GenerateCase(masm, FAST_ELEMENTS); |
6643 } | 6548 } |
6644 | 6549 |
6645 | 6550 |
6646 #undef __ | 6551 #undef __ |
6647 | 6552 |
6648 } } // namespace v8::internal | 6553 } } // namespace v8::internal |
6649 | 6554 |
6650 #endif // V8_TARGET_ARCH_X64 | 6555 #endif // V8_TARGET_ARCH_X64 |
OLD | NEW |