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

Side by Side Diff: src/ia32/code-stubs-ia32.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/heap.cc ('k') | src/runtime.h » ('j') | 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 3847 matching lines...) Expand 10 before | Expand all | Expand 10 after
3858 Register mask = scratch1; 3858 Register mask = scratch1;
3859 Register scratch = scratch2; 3859 Register scratch = scratch2;
3860 3860
3861 // Load the number string cache. 3861 // Load the number string cache.
3862 ExternalReference roots_address = 3862 ExternalReference roots_address =
3863 ExternalReference::roots_address(masm->isolate()); 3863 ExternalReference::roots_address(masm->isolate());
3864 __ mov(scratch, Immediate(Heap::kNumberStringCacheRootIndex)); 3864 __ mov(scratch, Immediate(Heap::kNumberStringCacheRootIndex));
3865 __ mov(number_string_cache, 3865 __ mov(number_string_cache,
3866 Operand::StaticArray(scratch, times_pointer_size, roots_address)); 3866 Operand::StaticArray(scratch, times_pointer_size, roots_address));
3867 // Make the hash mask from the length of the number string cache. It 3867 // Make the hash mask from the length of the number string cache. It
3868 // contains two elements (number and string) for each cache entry. 3868 // contains three elements (number, string and age) for each cache entry.
3869 __ mov(mask, FieldOperand(number_string_cache, FixedArray::kLengthOffset)); 3869 __ mov(mask, FieldOperand(number_string_cache, FixedArray::kLengthOffset));
3870 __ shr(mask, kSmiTagSize + 1); // Untag length and divide it by two. 3870 __ lea(scratch, Operand(mask, mask, times_1, 0));
3871 __ sub(mask, Immediate(1)); // Make mask. 3871 STATIC_ASSERT(Heap::kNSCSlotsPerEntry == 3);
3872 __ and_(mask, scratch); // Multiply mask by 2/3, making it a power of 2.
3873 // Make mask. It is 4 times the number of entries (2 times for Smi tag,
3874 // 2 times for the size of the array * 2/3).
3875 STATIC_ASSERT(kSmiTagSize == 1);
3876 STATIC_ASSERT(kPointerSize == 4);
3877 __ sub(mask, Immediate(kPointerSize - 1));
3872 3878
3873 // Calculate the entry in the number string cache. The hash value in the 3879 // Calculate the entry in the number string cache. The hash value in the
3874 // number string cache for smis is just the smi value, and the hash for 3880 // number string cache for smis is just the smi value, and the hash for
3875 // doubles is the xor of the upper and lower words. See 3881 // doubles is the xor of the upper and lower words. See
3876 // Heap::GetNumberStringCache. 3882 // Heap::GetNumberStringCache.
3877 Label smi_hash_calculated; 3883 Label smi_hash_calculated;
3878 Label load_result_from_cache; 3884 Label load_result_from_cache;
3879 if (object_is_smi) { 3885 if (object_is_smi) {
3880 __ mov(scratch, object); 3886 STATIC_ASSERT(kPointerSizeLog2 - kSmiTagSize == 1);
3881 __ SmiUntag(scratch); 3887 STATIC_ASSERT(kSmiTag == 0);
3888 __ lea(scratch, Operand(object, object, times_1, 0));
3882 } else { 3889 } else {
3883 Label not_smi; 3890 Label not_smi;
3884 STATIC_ASSERT(kSmiTag == 0); 3891 STATIC_ASSERT(kSmiTag == 0);
3885 __ JumpIfNotSmi(object, &not_smi, Label::kNear); 3892 __ JumpIfNotSmi(object, &not_smi, Label::kNear);
3886 __ mov(scratch, object); 3893 STATIC_ASSERT(kPointerSizeLog2 - kSmiTagSize == 1);
3887 __ SmiUntag(scratch); 3894 STATIC_ASSERT(kSmiTag == 0);
3895 __ lea(scratch, Operand(object, object, times_1, 0));
3888 __ jmp(&smi_hash_calculated, Label::kNear); 3896 __ jmp(&smi_hash_calculated, Label::kNear);
3889 __ bind(&not_smi); 3897 __ bind(&not_smi);
3890 __ cmp(FieldOperand(object, HeapObject::kMapOffset), 3898 __ cmp(FieldOperand(object, HeapObject::kMapOffset),
3891 masm->isolate()->factory()->heap_number_map()); 3899 masm->isolate()->factory()->heap_number_map());
3892 __ j(not_equal, not_found); 3900 __ j(not_equal, not_found);
3893 STATIC_ASSERT(8 == kDoubleSize); 3901 STATIC_ASSERT(8 == kDoubleSize);
3894 __ mov(scratch, FieldOperand(object, HeapNumber::kValueOffset)); 3902 __ mov(scratch, FieldOperand(object, HeapNumber::kValueOffset));
3895 __ xor_(scratch, FieldOperand(object, HeapNumber::kValueOffset + 4)); 3903 __ xor_(scratch, FieldOperand(object, HeapNumber::kValueOffset + 4));
3896 // Object is heap number and hash is now in scratch. Calculate cache index. 3904 // Object is heap number and hash is now in scratch. Scale hash to pointer
3905 // size and apply the mask.
3906 __ shl(scratch, kPointerSizeLog2);
3897 __ and_(scratch, mask); 3907 __ and_(scratch, mask);
3908 // Multiply by 3.
3909 STATIC_ASSERT(Heap::kNSCSlotsPerEntry == 3);
3910 __ lea(scratch, Operand(scratch, scratch, times_2, 0));
3898 Register index = scratch; 3911 Register index = scratch;
3899 Register probe = mask; 3912 Register probe = mask;
3900 __ mov(probe, 3913 __ mov(probe, FieldOperand(
3901 FieldOperand(number_string_cache, 3914 number_string_cache,
3902 index, 3915 index,
3903 times_twice_pointer_size, 3916 times_1,
3904 FixedArray::kHeaderSize)); 3917 FixedArray::kHeaderSize + kPointerSizeLog2 * Heap::kNSCNumberOffset));
3905 __ JumpIfSmi(probe, not_found); 3918 __ JumpIfSmi(probe, not_found);
3906 if (CpuFeatures::IsSupported(SSE2)) { 3919 if (CpuFeatures::IsSupported(SSE2)) {
3907 CpuFeatures::Scope fscope(SSE2); 3920 CpuFeatures::Scope fscope(SSE2);
3908 __ movdbl(xmm0, FieldOperand(object, HeapNumber::kValueOffset)); 3921 __ movdbl(xmm0, FieldOperand(object, HeapNumber::kValueOffset));
3909 __ movdbl(xmm1, FieldOperand(probe, HeapNumber::kValueOffset)); 3922 __ movdbl(xmm1, FieldOperand(probe, HeapNumber::kValueOffset));
3910 __ ucomisd(xmm0, xmm1); 3923 __ ucomisd(xmm0, xmm1);
3911 } else { 3924 } else {
3912 __ fld_d(FieldOperand(object, HeapNumber::kValueOffset)); 3925 __ fld_d(FieldOperand(object, HeapNumber::kValueOffset));
3913 __ fld_d(FieldOperand(probe, HeapNumber::kValueOffset)); 3926 __ fld_d(FieldOperand(probe, HeapNumber::kValueOffset));
3914 __ FCmp(); 3927 __ FCmp();
3915 } 3928 }
3916 __ j(parity_even, not_found); // Bail out if NaN is involved. 3929 __ j(parity_even, not_found); // Bail out if NaN is involved.
3917 __ j(not_equal, not_found); // The cache did not contain this value. 3930 __ j(not_equal, not_found); // The cache did not contain this value.
3918 __ jmp(&load_result_from_cache, Label::kNear); 3931 __ jmp(&load_result_from_cache, Label::kNear);
3919 } 3932 }
3920 3933
3921 __ bind(&smi_hash_calculated); 3934 __ bind(&smi_hash_calculated);
3922 // Object is smi and hash is now in scratch. Calculate cache index. 3935 // Object is smi and hash is now in scratch. Calculate cache index.
3923 __ and_(scratch, mask); 3936 __ and_(scratch, mask);
3937 // Multiply by 3.
3924 Register index = scratch; 3938 Register index = scratch;
3939 __ lea(index, Operand(scratch, scratch, times_2, 0));
3925 // Check if the entry is the smi we are looking for. 3940 // Check if the entry is the smi we are looking for.
3926 __ cmp(object, 3941 __ cmp(object, FieldOperand(
3927 FieldOperand(number_string_cache, 3942 number_string_cache,
3928 index, 3943 index,
3929 times_twice_pointer_size, 3944 times_1,
3930 FixedArray::kHeaderSize)); 3945 FixedArray::kHeaderSize + kPointerSizeLog2 * Heap::kNSCNumberOffset));
3931 __ j(not_equal, not_found); 3946 __ j(not_equal, not_found);
3932 3947
3933 // Get the result from the cache. 3948 // Get the result from the cache.
3934 __ bind(&load_result_from_cache); 3949 __ bind(&load_result_from_cache);
3950 int kAgeOffset = FixedArray::kHeaderSize + kPointerSize * Heap::kNSCAgeOffset;
3951 __ mov(FieldOperand(number_string_cache, index, times_1, kAgeOffset),
3952 Immediate(Smi::FromInt(Heap::kNSCMinAge))); // Reset age field.
3935 __ mov(result, 3953 __ mov(result,
3936 FieldOperand(number_string_cache, 3954 FieldOperand(
3937 index, 3955 number_string_cache,
3938 times_twice_pointer_size, 3956 index,
3939 FixedArray::kHeaderSize + kPointerSize)); 3957 times_1,
3958 FixedArray::kHeaderSize + kPointerSize * Heap::kNSCStringOffset));
3940 Counters* counters = masm->isolate()->counters(); 3959 Counters* counters = masm->isolate()->counters();
3941 __ IncrementCounter(counters->number_to_string_native(), 1); 3960 __ IncrementCounter(counters->number_to_string_native(), 1);
3942 } 3961 }
3943 3962
3944 3963
3945 void NumberToStringStub::Generate(MacroAssembler* masm) { 3964 void NumberToStringStub::Generate(MacroAssembler* masm) {
3946 Label runtime; 3965 Label runtime;
3947 3966
3948 __ mov(ebx, Operand(esp, kPointerSize)); 3967 __ mov(ebx, Operand(esp, kPointerSize));
3949 3968
(...skipping 3297 matching lines...) Expand 10 before | Expand all | Expand 10 after
7247 // Restore registers. 7266 // Restore registers.
7248 __ pop(eax); 7267 __ pop(eax);
7249 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); 7268 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset));
7250 } 7269 }
7251 7270
7252 #undef __ 7271 #undef __
7253 7272
7254 } } // namespace v8::internal 7273 } } // namespace v8::internal
7255 7274
7256 #endif // V8_TARGET_ARCH_IA32 7275 #endif // V8_TARGET_ARCH_IA32
OLDNEW
« src/heap.cc ('K') | « src/heap.cc ('k') | src/runtime.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698