| OLD | NEW |
| 1 // Copyright 2010 the V8 project authors. All rights reserved. | 1 // Copyright 2010 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 10906 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 10917 } | 10917 } |
| 10918 | 10918 |
| 10919 | 10919 |
| 10920 void NumberToStringStub::GenerateLookupNumberStringCache(MacroAssembler* masm, | 10920 void NumberToStringStub::GenerateLookupNumberStringCache(MacroAssembler* masm, |
| 10921 Register object, | 10921 Register object, |
| 10922 Register result, | 10922 Register result, |
| 10923 Register scratch1, | 10923 Register scratch1, |
| 10924 Register scratch2, | 10924 Register scratch2, |
| 10925 bool object_is_smi, | 10925 bool object_is_smi, |
| 10926 Label* not_found) { | 10926 Label* not_found) { |
| 10927 // Currently only lookup for smis. Check for smi if object is not known to be | |
| 10928 // a smi. | |
| 10929 if (!object_is_smi) { | |
| 10930 ASSERT(kSmiTag == 0); | |
| 10931 __ test(object, Immediate(kSmiTagMask)); | |
| 10932 __ j(not_zero, not_found); | |
| 10933 } | |
| 10934 | |
| 10935 // Use of registers. Register result is used as a temporary. | 10927 // Use of registers. Register result is used as a temporary. |
| 10936 Register number_string_cache = result; | 10928 Register number_string_cache = result; |
| 10937 Register mask = scratch1; | 10929 Register mask = scratch1; |
| 10938 Register scratch = scratch2; | 10930 Register scratch = scratch2; |
| 10939 | 10931 |
| 10940 // Load the number string cache. | 10932 // Load the number string cache. |
| 10941 ExternalReference roots_address = ExternalReference::roots_address(); | 10933 ExternalReference roots_address = ExternalReference::roots_address(); |
| 10942 __ mov(scratch, Immediate(Heap::kNumberStringCacheRootIndex)); | 10934 __ mov(scratch, Immediate(Heap::kNumberStringCacheRootIndex)); |
| 10943 __ mov(number_string_cache, | 10935 __ mov(number_string_cache, |
| 10944 Operand::StaticArray(scratch, times_pointer_size, roots_address)); | 10936 Operand::StaticArray(scratch, times_pointer_size, roots_address)); |
| 10945 // Make the hash mask from the length of the number string cache. It | 10937 // Make the hash mask from the length of the number string cache. It |
| 10946 // contains two elements (number and string) for each cache entry. | 10938 // contains two elements (number and string) for each cache entry. |
| 10947 __ mov(mask, FieldOperand(number_string_cache, FixedArray::kLengthOffset)); | 10939 __ mov(mask, FieldOperand(number_string_cache, FixedArray::kLengthOffset)); |
| 10948 __ shr(mask, 1); // Divide length by two (length is not a smi). | 10940 __ shr(mask, 1); // Divide length by two (length is not a smi). |
| 10949 __ sub(Operand(mask), Immediate(1)); // Make mask. | 10941 __ sub(Operand(mask), Immediate(1)); // Make mask. |
| 10942 |
| 10950 // Calculate the entry in the number string cache. The hash value in the | 10943 // Calculate the entry in the number string cache. The hash value in the |
| 10951 // number string cache for smis is just the smi value. | 10944 // number string cache for smis is just the smi value, and the hash for |
| 10952 __ mov(scratch, object); | 10945 // doubles is the xor of the upper and lower words. See |
| 10953 __ SmiUntag(scratch); | 10946 // Heap::GetNumberStringCache. |
| 10947 Label smi_hash_calculated; |
| 10948 Label load_result_from_cache; |
| 10949 if (object_is_smi) { |
| 10950 __ mov(scratch, object); |
| 10951 __ SmiUntag(scratch); |
| 10952 } else { |
| 10953 Label not_smi, hash_calculated; |
| 10954 ASSERT(kSmiTag == 0); |
| 10955 __ test(object, Immediate(kSmiTagMask)); |
| 10956 __ j(not_zero, ¬_smi); |
| 10957 __ mov(scratch, object); |
| 10958 __ SmiUntag(scratch); |
| 10959 __ jmp(&smi_hash_calculated); |
| 10960 __ bind(¬_smi); |
| 10961 __ cmp(FieldOperand(object, HeapObject::kMapOffset), |
| 10962 Factory::heap_number_map()); |
| 10963 __ j(not_equal, not_found); |
| 10964 ASSERT_EQ(8, kDoubleSize); |
| 10965 __ mov(scratch, FieldOperand(object, HeapNumber::kValueOffset)); |
| 10966 __ xor_(scratch, FieldOperand(object, HeapNumber::kValueOffset + 4)); |
| 10967 // Object is heap number and hash is now in scratch. Calculate cache index. |
| 10968 __ and_(scratch, Operand(mask)); |
| 10969 Register index = scratch; |
| 10970 Register probe = mask; |
| 10971 __ mov(probe, |
| 10972 FieldOperand(number_string_cache, |
| 10973 index, |
| 10974 times_twice_pointer_size, |
| 10975 FixedArray::kHeaderSize)); |
| 10976 __ test(probe, Immediate(kSmiTagMask)); |
| 10977 __ j(zero, not_found); |
| 10978 if (CpuFeatures::IsSupported(SSE2)) { |
| 10979 CpuFeatures::Scope fscope(SSE2); |
| 10980 __ movdbl(xmm0, FieldOperand(object, HeapNumber::kValueOffset)); |
| 10981 __ movdbl(xmm1, FieldOperand(probe, HeapNumber::kValueOffset)); |
| 10982 __ comisd(xmm0, xmm1); |
| 10983 } else { |
| 10984 __ fld_d(FieldOperand(object, HeapNumber::kValueOffset)); |
| 10985 __ fld_d(FieldOperand(probe, HeapNumber::kValueOffset)); |
| 10986 __ FCmp(); |
| 10987 } |
| 10988 __ j(parity_even, not_found); // Bail out if NaN is involved. |
| 10989 __ j(not_equal, not_found); // The cache did not contain this value. |
| 10990 __ jmp(&load_result_from_cache); |
| 10991 } |
| 10992 |
| 10993 __ bind(&smi_hash_calculated); |
| 10994 // Object is smi and hash is now in scratch. Calculate cache index. |
| 10954 __ and_(scratch, Operand(mask)); | 10995 __ and_(scratch, Operand(mask)); |
| 10996 Register index = scratch; |
| 10955 // Check if the entry is the smi we are looking for. | 10997 // Check if the entry is the smi we are looking for. |
| 10956 __ cmp(object, | 10998 __ cmp(object, |
| 10957 FieldOperand(number_string_cache, | 10999 FieldOperand(number_string_cache, |
| 10958 scratch, | 11000 index, |
| 10959 times_twice_pointer_size, | 11001 times_twice_pointer_size, |
| 10960 FixedArray::kHeaderSize)); | 11002 FixedArray::kHeaderSize)); |
| 10961 __ j(not_equal, not_found); | 11003 __ j(not_equal, not_found); |
| 10962 | 11004 |
| 10963 // Get the result from the cache. | 11005 // Get the result from the cache. |
| 11006 __ bind(&load_result_from_cache); |
| 10964 __ mov(result, | 11007 __ mov(result, |
| 10965 FieldOperand(number_string_cache, | 11008 FieldOperand(number_string_cache, |
| 10966 scratch, | 11009 index, |
| 10967 times_twice_pointer_size, | 11010 times_twice_pointer_size, |
| 10968 FixedArray::kHeaderSize + kPointerSize)); | 11011 FixedArray::kHeaderSize + kPointerSize)); |
| 10969 __ IncrementCounter(&Counters::number_to_string_native, 1); | 11012 __ IncrementCounter(&Counters::number_to_string_native, 1); |
| 10970 } | 11013 } |
| 10971 | 11014 |
| 10972 | 11015 |
| 10973 void NumberToStringStub::Generate(MacroAssembler* masm) { | 11016 void NumberToStringStub::Generate(MacroAssembler* masm) { |
| 10974 Label runtime; | 11017 Label runtime; |
| 10975 | 11018 |
| 10976 __ mov(ebx, Operand(esp, kPointerSize)); | 11019 __ mov(ebx, Operand(esp, kPointerSize)); |
| 10977 | 11020 |
| 10978 // Generate code to lookup number in the number string cache. | 11021 // Generate code to lookup number in the number string cache. |
| 10979 GenerateLookupNumberStringCache(masm, ebx, eax, ecx, edx, false, &runtime); | 11022 GenerateLookupNumberStringCache(masm, ebx, eax, ecx, edx, false, &runtime); |
| 10980 __ ret(1 * kPointerSize); | 11023 __ ret(1 * kPointerSize); |
| 10981 | 11024 |
| 10982 __ bind(&runtime); | 11025 __ bind(&runtime); |
| 10983 // Handle number to string in the runtime system if not found in the cache. | 11026 // Handle number to string in the runtime system if not found in the cache. |
| 10984 __ TailCallRuntime(Runtime::kNumberToString, 1, 1); | 11027 __ TailCallRuntime(Runtime::kNumberToStringSkipCache, 1, 1); |
| 10985 } | 11028 } |
| 10986 | 11029 |
| 10987 | 11030 |
| 10988 void RecordWriteStub::Generate(MacroAssembler* masm) { | 11031 void RecordWriteStub::Generate(MacroAssembler* masm) { |
| 10989 masm->RecordWriteHelper(object_, addr_, scratch_); | 11032 masm->RecordWriteHelper(object_, addr_, scratch_); |
| 10990 masm->ret(0); | 11033 masm->ret(0); |
| 10991 } | 11034 } |
| 10992 | 11035 |
| 10993 | 11036 |
| 10994 void CompareStub::Generate(MacroAssembler* masm) { | 11037 void CompareStub::Generate(MacroAssembler* masm) { |
| (...skipping 1600 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 12595 | 12638 |
| 12596 // Call the runtime; it returns -1 (less), 0 (equal), or 1 (greater) | 12639 // Call the runtime; it returns -1 (less), 0 (equal), or 1 (greater) |
| 12597 // tagged as a small integer. | 12640 // tagged as a small integer. |
| 12598 __ bind(&runtime); | 12641 __ bind(&runtime); |
| 12599 __ TailCallRuntime(Runtime::kStringCompare, 2, 1); | 12642 __ TailCallRuntime(Runtime::kStringCompare, 2, 1); |
| 12600 } | 12643 } |
| 12601 | 12644 |
| 12602 #undef __ | 12645 #undef __ |
| 12603 | 12646 |
| 12604 } } // namespace v8::internal | 12647 } } // namespace v8::internal |
| OLD | NEW |