Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(67)

Side by Side Diff: src/x64/code-stubs-x64.cc

Issue 8341014: Age the number string cache so it does not keep strings Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: Created 9 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« src/heap.cc ('K') | « src/runtime.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 2912 matching lines...) Expand 10 before | Expand all | Expand 10 after
2923 Label* not_found) { 2923 Label* not_found) {
2924 // Use of registers. Register result is used as a temporary. 2924 // Use of registers. Register result is used as a temporary.
2925 Register number_string_cache = result; 2925 Register number_string_cache = result;
2926 Register mask = scratch1; 2926 Register mask = scratch1;
2927 Register scratch = scratch2; 2927 Register scratch = scratch2;
2928 2928
2929 // Load the number string cache. 2929 // Load the number string cache.
2930 __ LoadRoot(number_string_cache, Heap::kNumberStringCacheRootIndex); 2930 __ LoadRoot(number_string_cache, Heap::kNumberStringCacheRootIndex);
2931 2931
2932 // Make the hash mask from the length of the number string cache. It 2932 // Make the hash mask from the length of the number string cache. It
2933 // contains two elements (number and string) for each cache entry. 2933 // contains three elements (number, string and age) for each cache entry.
2934 __ SmiToInteger32( 2934 __ SmiToInteger32(
2935 mask, FieldOperand(number_string_cache, FixedArray::kLengthOffset)); 2935 scratch, FieldOperand(number_string_cache, FixedArray::kLengthOffset));
2936 __ shrl(mask, Immediate(1)); 2936
2937 __ subq(mask, Immediate(1)); // Make mask. 2937 STATIC_ASSERT(Heap::kNSCSlotsPerEntry == 3);
2938 // mask = scratch / 3 - 1, making it one less than a power of 2.
2939 __ lea(mask, Operand(scratch, -1));
2940 __ and_(scratch, mask);
2941 __ xor_(mask, scratch);
2938 2942
2939 // Calculate the entry in the number string cache. The hash value in the 2943 // Calculate the entry in the number string cache. The hash value in the
2940 // number string cache for smis is just the smi value, and the hash for 2944 // number string cache for smis is just the smi value, and the hash for
2941 // doubles is the xor of the upper and lower words. See 2945 // doubles is the xor of the upper and lower words. See
2942 // Heap::GetNumberStringCache. 2946 // Heap::GetNumberStringCache.
2943 Label is_smi; 2947 Label is_smi;
2944 Label load_result_from_cache; 2948 Label load_result_from_cache;
2945 Factory* factory = masm->isolate()->factory(); 2949 Factory* factory = masm->isolate()->factory();
2946 if (!object_is_smi) { 2950 if (!object_is_smi) {
2947 __ JumpIfSmi(object, &is_smi); 2951 __ JumpIfSmi(object, &is_smi);
2948 __ CheckMap(object, 2952 __ CheckMap(object,
2949 factory->heap_number_map(), 2953 factory->heap_number_map(),
2950 not_found, 2954 not_found,
2951 DONT_DO_SMI_CHECK); 2955 DONT_DO_SMI_CHECK);
2952 2956
2953 STATIC_ASSERT(8 == kDoubleSize); 2957 STATIC_ASSERT(8 == kDoubleSize);
2954 __ movl(scratch, FieldOperand(object, HeapNumber::kValueOffset + 4)); 2958 __ movl(scratch, FieldOperand(object, HeapNumber::kValueOffset + 4));
2955 __ xor_(scratch, FieldOperand(object, HeapNumber::kValueOffset)); 2959 __ xor_(scratch, FieldOperand(object, HeapNumber::kValueOffset));
2956 GenerateConvertHashCodeToIndex(masm, scratch, mask); 2960 GenerateConvertHashCodeToIndex(masm, scratch, mask);
2957 2961
2958 Register index = scratch; 2962 Register index = scratch;
2959 Register probe = mask; 2963 Register probe = mask;
2960 __ movq(probe, 2964 __ movq(probe, FieldOperand(
2961 FieldOperand(number_string_cache, 2965 number_string_cache,
2962 index, 2966 index,
2963 times_1, 2967 times_pointer_size,
2964 FixedArray::kHeaderSize)); 2968 FixedArray::kHeaderSize + kPointerSize * Heap::kNSCNumberOffset));
2965 __ JumpIfSmi(probe, not_found); 2969 __ JumpIfSmi(probe, not_found);
2966 __ movsd(xmm0, FieldOperand(object, HeapNumber::kValueOffset)); 2970 __ movsd(xmm0, FieldOperand(object, HeapNumber::kValueOffset));
2967 __ movsd(xmm1, FieldOperand(probe, HeapNumber::kValueOffset)); 2971 __ movsd(xmm1, FieldOperand(probe, HeapNumber::kValueOffset));
2968 __ ucomisd(xmm0, xmm1); 2972 __ ucomisd(xmm0, xmm1);
2969 __ j(parity_even, not_found); // Bail out if NaN is involved. 2973 __ j(parity_even, not_found); // Bail out if NaN is involved.
2970 __ j(not_equal, not_found); // The cache did not contain this value. 2974 __ j(not_equal, not_found); // The cache did not contain this value.
2971 __ jmp(&load_result_from_cache); 2975 __ jmp(&load_result_from_cache);
2972 } 2976 }
2973 2977
2974 __ bind(&is_smi); 2978 __ bind(&is_smi);
2975 __ SmiToInteger32(scratch, object); 2979 __ SmiToInteger32(scratch, object);
2976 GenerateConvertHashCodeToIndex(masm, scratch, mask); 2980 GenerateConvertHashCodeToIndex(masm, scratch, mask);
2977 2981
2978 Register index = scratch; 2982 Register index = scratch;
2979 // Check if the entry is the smi we are looking for. 2983 // Check if the entry is the smi we are looking for.
2980 __ cmpq(object, 2984 __ cmpq(object, FieldOperand(
2981 FieldOperand(number_string_cache, 2985 number_string_cache,
2982 index, 2986 index,
2983 times_1, 2987 times_pointer_size,
2984 FixedArray::kHeaderSize)); 2988 FixedArray::kHeaderSize + kPointerSize * Heap::kNSCNumberOffset));
2985 __ j(not_equal, not_found); 2989 __ j(not_equal, not_found);
2986 2990
2987 // Get the result from the cache. 2991 // Get the result from the cache.
2988 __ bind(&load_result_from_cache); 2992 __ bind(&load_result_from_cache);
2989 __ movq(result, 2993 int kAgeOffset = FixedArray::kHeaderSize + kPointerSize * Heap::kNSCAgeOffset;
2990 FieldOperand(number_string_cache, 2994 __ Move(FieldOperand(number_string_cache,
2991 index, 2995 index,
2992 times_1, 2996 times_pointer_size,
2993 FixedArray::kHeaderSize + kPointerSize)); 2997 kAgeOffset),
2998 Smi::FromInt(Heap::kNSCMinAge)); // Reset age field.
2999 __ movq(result, FieldOperand(
3000 number_string_cache,
3001 index,
3002 times_pointer_size,
3003 FixedArray::kHeaderSize + kPointerSize * Heap::kNSCStringOffset));
2994 Counters* counters = masm->isolate()->counters(); 3004 Counters* counters = masm->isolate()->counters();
2995 __ IncrementCounter(counters->number_to_string_native(), 1); 3005 __ IncrementCounter(counters->number_to_string_native(), 1);
2996 } 3006 }
2997 3007
2998 3008
2999 void NumberToStringStub::GenerateConvertHashCodeToIndex(MacroAssembler* masm, 3009 void NumberToStringStub::GenerateConvertHashCodeToIndex(MacroAssembler* masm,
3000 Register hash, 3010 Register hash,
3001 Register mask) { 3011 Register mask) {
3002 __ and_(hash, mask); 3012 __ and_(hash, mask);
3003 // Each entry in string cache consists of two pointer sized fields, 3013 // Each entry in string cache consists of three pointer sized fields,
3004 // but times_twice_pointer_size (multiplication by 16) scale factor 3014 // so we multiply by 3 and we will use times_pointer_size scaling.
3005 // is not supported by addrmode on x64 platform. 3015 __ lea(hash, Operand(hash, hash, times_2, 0));
3006 // So we have to premultiply entry index before lookup.
3007 __ shl(hash, Immediate(kPointerSizeLog2 + 1));
3008 } 3016 }
3009 3017
3010 3018
3011 void NumberToStringStub::Generate(MacroAssembler* masm) { 3019 void NumberToStringStub::Generate(MacroAssembler* masm) {
3012 Label runtime; 3020 Label runtime;
3013 3021
3014 __ movq(rbx, Operand(rsp, kPointerSize)); 3022 __ movq(rbx, Operand(rsp, kPointerSize));
3015 3023
3016 // Generate code to lookup number in the number string cache. 3024 // Generate code to lookup number in the number string cache.
3017 GenerateLookupNumberStringCache(masm, rbx, rax, r8, r9, false, &runtime); 3025 GenerateLookupNumberStringCache(masm, rbx, rax, r8, r9, false, &runtime);
(...skipping 3074 matching lines...) Expand 10 before | Expand all | Expand 10 after
6092 OMIT_SMI_CHECK); 6100 OMIT_SMI_CHECK);
6093 __ pop(rax); 6101 __ pop(rax);
6094 __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); 6102 __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset));
6095 } 6103 }
6096 6104
6097 #undef __ 6105 #undef __
6098 6106
6099 } } // namespace v8::internal 6107 } } // namespace v8::internal
6100 6108
6101 #endif // V8_TARGET_ARCH_X64 6109 #endif // V8_TARGET_ARCH_X64
OLDNEW
« src/heap.cc ('K') | « src/runtime.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698