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 7674 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7685 __ movq(rax, Operand(rsp, kLastMatchInfoOffset)); | 7685 __ movq(rax, Operand(rsp, kLastMatchInfoOffset)); |
7686 __ ret(4 * kPointerSize); | 7686 __ ret(4 * kPointerSize); |
7687 | 7687 |
7688 // Do the runtime call to execute the regexp. | 7688 // Do the runtime call to execute the regexp. |
7689 __ bind(&runtime); | 7689 __ bind(&runtime); |
7690 __ TailCallRuntime(Runtime::kRegExpExec, 4, 1); | 7690 __ TailCallRuntime(Runtime::kRegExpExec, 4, 1); |
7691 #endif // V8_INTERPRETED_REGEXP | 7691 #endif // V8_INTERPRETED_REGEXP |
7692 } | 7692 } |
7693 | 7693 |
7694 | 7694 |
| 7695 void NumberToStringStub::GenerateConvertHashCodeToIndex(MacroAssembler* masm, |
| 7696 Register hash, |
| 7697 Register mask) { |
| 7698 __ andl(hash, mask); |
| 7699 // Each entry in string cache consists of two pointer sized fields, |
| 7700 // but times_twice_pointer_size (multiplication by 16) scale factor |
| 7701 // is not supported by addrmode on x64 platform. |
| 7702 // So we have to premultiply entry index before lookup. |
| 7703 __ shl(hash, Immediate(kPointerSizeLog2 + 1)); |
| 7704 } |
| 7705 |
| 7706 |
7695 void NumberToStringStub::GenerateLookupNumberStringCache(MacroAssembler* masm, | 7707 void NumberToStringStub::GenerateLookupNumberStringCache(MacroAssembler* masm, |
7696 Register object, | 7708 Register object, |
7697 Register result, | 7709 Register result, |
7698 Register scratch1, | 7710 Register scratch1, |
7699 Register scratch2, | 7711 Register scratch2, |
7700 bool object_is_smi, | 7712 bool object_is_smi, |
7701 Label* not_found) { | 7713 Label* not_found) { |
7702 // Currently only lookup for smis. Check for smi if object is not known to be | |
7703 // a smi. | |
7704 if (!object_is_smi) { | |
7705 __ JumpIfNotSmi(object, not_found); | |
7706 } | |
7707 | |
7708 // Use of registers. Register result is used as a temporary. | 7714 // Use of registers. Register result is used as a temporary. |
7709 Register number_string_cache = result; | 7715 Register number_string_cache = result; |
7710 Register mask = scratch1; | 7716 Register mask = scratch1; |
7711 Register scratch = scratch2; | 7717 Register scratch = scratch2; |
7712 | 7718 |
7713 // Load the number string cache. | 7719 // Load the number string cache. |
7714 __ LoadRoot(number_string_cache, Heap::kNumberStringCacheRootIndex); | 7720 __ LoadRoot(number_string_cache, Heap::kNumberStringCacheRootIndex); |
7715 | 7721 |
7716 // Make the hash mask from the length of the number string cache. It | 7722 // Make the hash mask from the length of the number string cache. It |
7717 // contains two elements (number and string) for each cache entry. | 7723 // contains two elements (number and string) for each cache entry. |
7718 __ movl(mask, FieldOperand(number_string_cache, FixedArray::kLengthOffset)); | 7724 __ movl(mask, FieldOperand(number_string_cache, FixedArray::kLengthOffset)); |
7719 __ shrl(mask, Immediate(1)); // Divide length by two (length is not a smi). | 7725 __ shrl(mask, Immediate(1)); // Divide length by two (length is not a smi). |
7720 __ subl(mask, Immediate(1)); // Make mask. | 7726 __ subl(mask, Immediate(1)); // Make mask. |
7721 | 7727 |
7722 // Calculate the entry in the number string cache. The hash value in the | 7728 // Calculate the entry in the number string cache. The hash value in the |
7723 // number string cache for smis is just the smi value. | 7729 // number string cache for smis is just the smi value, and the hash for |
| 7730 // doubles is the xor of the upper and lower words. See |
| 7731 // Heap::GetNumberStringCache. |
| 7732 Label is_smi; |
| 7733 Label load_result_from_cache; |
| 7734 if (!object_is_smi) { |
| 7735 __ JumpIfSmi(object, &is_smi); |
| 7736 __ CheckMap(object, Factory::heap_number_map(), not_found, true); |
| 7737 |
| 7738 ASSERT_EQ(8, kDoubleSize); |
| 7739 __ movl(scratch, FieldOperand(object, HeapNumber::kValueOffset)); |
| 7740 __ xor_(scratch, FieldOperand(object, HeapNumber::kValueOffset + 4)); |
| 7741 GenerateConvertHashCodeToIndex(masm, scratch, mask); |
| 7742 |
| 7743 Register index = scratch; |
| 7744 Register probe = mask; |
| 7745 __ movq(probe, |
| 7746 FieldOperand(number_string_cache, |
| 7747 index, |
| 7748 times_1, |
| 7749 FixedArray::kHeaderSize)); |
| 7750 __ JumpIfSmi(probe, not_found); |
| 7751 ASSERT(CpuFeatures::IsSupported(SSE2)); |
| 7752 CpuFeatures::Scope fscope(SSE2); |
| 7753 __ movsd(xmm0, FieldOperand(object, HeapNumber::kValueOffset)); |
| 7754 __ movsd(xmm1, FieldOperand(probe, HeapNumber::kValueOffset)); |
| 7755 __ comisd(xmm0, xmm1); |
| 7756 __ j(parity_even, not_found); // Bail out if NaN is involved. |
| 7757 __ j(not_equal, not_found); // The cache did not contain this value. |
| 7758 __ jmp(&load_result_from_cache); |
| 7759 } |
| 7760 |
| 7761 __ bind(&is_smi); |
7724 __ movq(scratch, object); | 7762 __ movq(scratch, object); |
7725 __ SmiToInteger32(scratch, scratch); | 7763 __ SmiToInteger32(scratch, scratch); |
7726 __ andl(scratch, mask); | 7764 GenerateConvertHashCodeToIndex(masm, scratch, mask); |
7727 | 7765 |
7728 // Each entry in string cache consists of two pointer sized fields, | 7766 Register index = scratch; |
7729 // but times_twice_pointer_size (multiplication by 16) scale factor | |
7730 // is not supported by addrmode on x64 platform. | |
7731 // So we have to premultiply entry index before lookup | |
7732 __ shl(scratch, Immediate(kPointerSizeLog2 + 1)); | |
7733 // Check if the entry is the smi we are looking for. | 7767 // Check if the entry is the smi we are looking for. |
7734 __ cmpq(object, | 7768 __ cmpq(object, |
7735 FieldOperand(number_string_cache, | 7769 FieldOperand(number_string_cache, |
7736 scratch, | 7770 index, |
7737 times_1, | 7771 times_1, |
7738 FixedArray::kHeaderSize)); | 7772 FixedArray::kHeaderSize)); |
7739 __ j(not_equal, not_found); | 7773 __ j(not_equal, not_found); |
7740 | 7774 |
7741 // Get the result from the cache. | 7775 // Get the result from the cache. |
| 7776 __ bind(&load_result_from_cache); |
7742 __ movq(result, | 7777 __ movq(result, |
7743 FieldOperand(number_string_cache, | 7778 FieldOperand(number_string_cache, |
7744 scratch, | 7779 index, |
7745 times_1, | 7780 times_1, |
7746 FixedArray::kHeaderSize + kPointerSize)); | 7781 FixedArray::kHeaderSize + kPointerSize)); |
7747 __ IncrementCounter(&Counters::number_to_string_native, 1); | 7782 __ IncrementCounter(&Counters::number_to_string_native, 1); |
7748 } | 7783 } |
7749 | 7784 |
7750 | 7785 |
7751 void NumberToStringStub::Generate(MacroAssembler* masm) { | 7786 void NumberToStringStub::Generate(MacroAssembler* masm) { |
7752 Label runtime; | 7787 Label runtime; |
7753 | 7788 |
7754 __ movq(rbx, Operand(rsp, kPointerSize)); | 7789 __ movq(rbx, Operand(rsp, kPointerSize)); |
7755 | 7790 |
7756 // Generate code to lookup number in the number string cache. | 7791 // Generate code to lookup number in the number string cache. |
7757 GenerateLookupNumberStringCache(masm, rbx, rax, r8, r9, false, &runtime); | 7792 GenerateLookupNumberStringCache(masm, rbx, rax, r8, r9, false, &runtime); |
7758 __ ret(1 * kPointerSize); | 7793 __ ret(1 * kPointerSize); |
7759 | 7794 |
7760 __ bind(&runtime); | 7795 __ bind(&runtime); |
7761 // Handle number to string in the runtime system if not found in the cache. | 7796 // Handle number to string in the runtime system if not found in the cache. |
7762 __ TailCallRuntime(Runtime::kNumberToString, 1, 1); | 7797 __ TailCallRuntime(Runtime::kNumberToStringSkipCache, 1, 1); |
7763 } | 7798 } |
7764 | 7799 |
7765 | 7800 |
7766 void CompareStub::Generate(MacroAssembler* masm) { | 7801 void CompareStub::Generate(MacroAssembler* masm) { |
7767 Label call_builtin, done; | 7802 Label call_builtin, done; |
7768 | 7803 |
7769 // NOTICE! This code is only reached after a smi-fast-case check, so | 7804 // NOTICE! This code is only reached after a smi-fast-case check, so |
7770 // it is certain that at least one operand isn't a smi. | 7805 // it is certain that at least one operand isn't a smi. |
7771 | 7806 |
7772 if (cc_ == equal) { // Both strict and non-strict. | 7807 if (cc_ == equal) { // Both strict and non-strict. |
(...skipping 2694 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10467 // Call the function from C++. | 10502 // Call the function from C++. |
10468 return FUNCTION_CAST<ModuloFunction>(buffer); | 10503 return FUNCTION_CAST<ModuloFunction>(buffer); |
10469 } | 10504 } |
10470 | 10505 |
10471 #endif | 10506 #endif |
10472 | 10507 |
10473 | 10508 |
10474 #undef __ | 10509 #undef __ |
10475 | 10510 |
10476 } } // namespace v8::internal | 10511 } } // namespace v8::internal |
OLD | NEW |