| 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 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 79 Isolate* isolate, | 79 Isolate* isolate, |
| 80 CodeStubInterfaceDescriptor* descriptor) { | 80 CodeStubInterfaceDescriptor* descriptor) { |
| 81 // x3: object literals array | 81 // x3: object literals array |
| 82 // x2: object literal index | 82 // x2: object literal index |
| 83 // x1: constant properties | 83 // x1: constant properties |
| 84 // x0: object literal flags | 84 // x0: object literal flags |
| 85 static Register registers[] = { x3, x2, x1, x0 }; | 85 static Register registers[] = { x3, x2, x1, x0 }; |
| 86 descriptor->register_param_count_ = sizeof(registers) / sizeof(registers[0]); | 86 descriptor->register_param_count_ = sizeof(registers) / sizeof(registers[0]); |
| 87 descriptor->register_params_ = registers; | 87 descriptor->register_params_ = registers; |
| 88 descriptor->deoptimization_handler_ = | 88 descriptor->deoptimization_handler_ = |
| 89 Runtime::FunctionForId(Runtime::kCreateObjectLiteralShallow)->entry; | 89 Runtime::FunctionForId(Runtime::kCreateObjectLiteral)->entry; |
| 90 } | 90 } |
| 91 | 91 |
| 92 | 92 |
| 93 void CreateAllocationSiteStub::InitializeInterfaceDescriptor( | 93 void CreateAllocationSiteStub::InitializeInterfaceDescriptor( |
| 94 Isolate* isolate, | 94 Isolate* isolate, |
| 95 CodeStubInterfaceDescriptor* descriptor) { | 95 CodeStubInterfaceDescriptor* descriptor) { |
| 96 // x2: cache cell | 96 // x2: cache cell |
| 97 static Register registers[] = { x2 }; | 97 static Register registers[] = { x2 }; |
| 98 descriptor->register_param_count_ = sizeof(registers) / sizeof(registers[0]); | 98 descriptor->register_param_count_ = sizeof(registers) / sizeof(registers[0]); |
| 99 descriptor->register_params_ = registers; | 99 descriptor->register_params_ = registers; |
| (...skipping 2193 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2293 | 2293 |
| 2294 // The call succeeded, so unwind the stack and return. | 2294 // The call succeeded, so unwind the stack and return. |
| 2295 | 2295 |
| 2296 // Restore callee-saved registers x21-x23. | 2296 // Restore callee-saved registers x21-x23. |
| 2297 __ Mov(x11, argc); | 2297 __ Mov(x11, argc); |
| 2298 | 2298 |
| 2299 __ Peek(argv, 1 * kPointerSize); | 2299 __ Peek(argv, 1 * kPointerSize); |
| 2300 __ Peek(argc, 2 * kPointerSize); | 2300 __ Peek(argc, 2 * kPointerSize); |
| 2301 __ Peek(target, 3 * kPointerSize); | 2301 __ Peek(target, 3 * kPointerSize); |
| 2302 | 2302 |
| 2303 __ LeaveExitFrame(save_doubles_, x10); | 2303 __ LeaveExitFrame(save_doubles_, x10, true); |
| 2304 ASSERT(jssp.Is(__ StackPointer())); | 2304 ASSERT(jssp.Is(__ StackPointer())); |
| 2305 // Pop or drop the remaining stack slots and return from the stub. | 2305 // Pop or drop the remaining stack slots and return from the stub. |
| 2306 // jssp[24]: Arguments array (of size argc), including receiver. | 2306 // jssp[24]: Arguments array (of size argc), including receiver. |
| 2307 // jssp[16]: Preserved x23 (used for target). | 2307 // jssp[16]: Preserved x23 (used for target). |
| 2308 // jssp[8]: Preserved x22 (used for argc). | 2308 // jssp[8]: Preserved x22 (used for argc). |
| 2309 // jssp[0]: Preserved x21 (used for argv). | 2309 // jssp[0]: Preserved x21 (used for argv). |
| 2310 __ Drop(x11); | 2310 __ Drop(x11); |
| 2311 __ Ret(); | 2311 __ Ret(); |
| 2312 | 2312 |
| 2313 // The stack pointer is still csp if we aren't returning, and the frame | 2313 // The stack pointer is still csp if we aren't returning, and the frame |
| (...skipping 1500 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3814 __ Add(x6, x10, x11); | 3814 __ Add(x6, x10, x11); |
| 3815 | 3815 |
| 3816 // Argument 8 (x7): Indicate that this is a direct call from JavaScript. | 3816 // Argument 8 (x7): Indicate that this is a direct call from JavaScript. |
| 3817 __ Mov(x7, 1); | 3817 __ Mov(x7, 1); |
| 3818 | 3818 |
| 3819 // Locate the code entry and call it. | 3819 // Locate the code entry and call it. |
| 3820 __ Add(code_object, code_object, Code::kHeaderSize - kHeapObjectTag); | 3820 __ Add(code_object, code_object, Code::kHeaderSize - kHeapObjectTag); |
| 3821 DirectCEntryStub stub; | 3821 DirectCEntryStub stub; |
| 3822 stub.GenerateCall(masm, code_object); | 3822 stub.GenerateCall(masm, code_object); |
| 3823 | 3823 |
| 3824 __ LeaveExitFrame(false, x10); | 3824 __ LeaveExitFrame(false, x10, true); |
| 3825 | 3825 |
| 3826 // The generated regexp code returns an int32 in w0. | 3826 // The generated regexp code returns an int32 in w0. |
| 3827 Label failure, exception; | 3827 Label failure, exception; |
| 3828 __ CompareAndBranch(w0, NativeRegExpMacroAssembler::FAILURE, eq, &failure); | 3828 __ CompareAndBranch(w0, NativeRegExpMacroAssembler::FAILURE, eq, &failure); |
| 3829 __ CompareAndBranch(w0, | 3829 __ CompareAndBranch(w0, |
| 3830 NativeRegExpMacroAssembler::EXCEPTION, | 3830 NativeRegExpMacroAssembler::EXCEPTION, |
| 3831 eq, | 3831 eq, |
| 3832 &exception); | 3832 &exception); |
| 3833 __ CompareAndBranch(w0, NativeRegExpMacroAssembler::RETRY, eq, &runtime); | 3833 __ CompareAndBranch(w0, NativeRegExpMacroAssembler::RETRY, eq, &runtime); |
| 3834 | 3834 |
| (...skipping 947 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4782 __ Add(stub_entry, x0, Code::kHeaderSize - kHeapObjectTag); | 4782 __ Add(stub_entry, x0, Code::kHeaderSize - kHeapObjectTag); |
| 4783 // Restore caller-saved registers. | 4783 // Restore caller-saved registers. |
| 4784 __ Pop(lr, x0, x1); | 4784 __ Pop(lr, x0, x1); |
| 4785 } | 4785 } |
| 4786 | 4786 |
| 4787 // Tail-call to the new stub. | 4787 // Tail-call to the new stub. |
| 4788 __ Jump(stub_entry); | 4788 __ Jump(stub_entry); |
| 4789 } | 4789 } |
| 4790 | 4790 |
| 4791 | 4791 |
| 4792 void NumberToStringStub::GenerateLookupNumberStringCache(MacroAssembler* masm, | |
| 4793 Register object, | |
| 4794 Register result, | |
| 4795 Register scratch1, | |
| 4796 Register scratch2, | |
| 4797 Register scratch3, | |
| 4798 Label* not_found) { | |
| 4799 ASSERT(!AreAliased(object, result, scratch1, scratch2, scratch3)); | |
| 4800 | |
| 4801 // Use of registers. Register result is used as a temporary. | |
| 4802 Register number_string_cache = result; | |
| 4803 Register mask = scratch3; | |
| 4804 | |
| 4805 // Load the number string cache. | |
| 4806 __ LoadRoot(number_string_cache, Heap::kNumberStringCacheRootIndex); | |
| 4807 | |
| 4808 // Make the hash mask from the length of the number string cache. It | |
| 4809 // contains two elements (number and string) for each cache entry. | |
| 4810 __ Ldrsw(mask, UntagSmiFieldMemOperand(number_string_cache, | |
| 4811 FixedArray::kLengthOffset)); | |
| 4812 __ Asr(mask, mask, 1); // Divide length by two. | |
| 4813 __ Sub(mask, mask, 1); // Make mask. | |
| 4814 | |
| 4815 // Calculate the entry in the number string cache. The hash value in the | |
| 4816 // number string cache for smis is just the smi value, and the hash for | |
| 4817 // doubles is the xor of the upper and lower words. See | |
| 4818 // Heap::GetNumberStringCache. | |
| 4819 Isolate* isolate = masm->isolate(); | |
| 4820 Label is_smi; | |
| 4821 Label load_result_from_cache; | |
| 4822 | |
| 4823 __ JumpIfSmi(object, &is_smi); | |
| 4824 __ CheckMap(object, scratch1, Heap::kHeapNumberMapRootIndex, not_found, | |
| 4825 DONT_DO_SMI_CHECK); | |
| 4826 | |
| 4827 STATIC_ASSERT(kDoubleSize == (kWRegSizeInBytes * 2)); | |
| 4828 __ Add(scratch1, object, HeapNumber::kValueOffset - kHeapObjectTag); | |
| 4829 __ Ldp(scratch1.W(), scratch2.W(), MemOperand(scratch1)); | |
| 4830 __ Eor(scratch1, scratch1, scratch2); | |
| 4831 __ And(scratch1, scratch1, mask); | |
| 4832 | |
| 4833 // Calculate address of entry in string cache: each entry consists of two | |
| 4834 // pointer sized fields. | |
| 4835 __ Add(scratch1, number_string_cache, | |
| 4836 Operand(scratch1, LSL, kPointerSizeLog2 + 1)); | |
| 4837 | |
| 4838 Register probe = mask; | |
| 4839 __ Ldr(probe, FieldMemOperand(scratch1, FixedArray::kHeaderSize)); | |
| 4840 __ JumpIfSmi(probe, not_found); | |
| 4841 __ Ldr(d0, FieldMemOperand(object, HeapNumber::kValueOffset)); | |
| 4842 __ Ldr(d1, FieldMemOperand(probe, HeapNumber::kValueOffset)); | |
| 4843 __ Fcmp(d0, d1); | |
| 4844 __ B(ne, not_found); | |
| 4845 __ B(&load_result_from_cache); | |
| 4846 | |
| 4847 __ Bind(&is_smi); | |
| 4848 Register scratch = scratch1; | |
| 4849 __ And(scratch, mask, Operand::UntagSmi(object)); | |
| 4850 // Calculate address of entry in string cache: each entry consists | |
| 4851 // of two pointer sized fields. | |
| 4852 __ Add(scratch, | |
| 4853 number_string_cache, | |
| 4854 Operand(scratch, LSL, kPointerSizeLog2 + 1)); | |
| 4855 | |
| 4856 // Check if the entry is the smi we are looking for. | |
| 4857 __ Ldr(probe, FieldMemOperand(scratch, FixedArray::kHeaderSize)); | |
| 4858 __ Cmp(object, probe); | |
| 4859 __ B(ne, not_found); | |
| 4860 | |
| 4861 // Get the result from the cache. | |
| 4862 __ Bind(&load_result_from_cache); | |
| 4863 __ Ldr(result, | |
| 4864 FieldMemOperand(scratch, FixedArray::kHeaderSize + kPointerSize)); | |
| 4865 __ IncrementCounter(isolate->counters()->number_to_string_native(), 1, | |
| 4866 scratch1, scratch2); | |
| 4867 } | |
| 4868 | |
| 4869 | |
| 4870 void NumberToStringStub::Generate(MacroAssembler* masm) { | 4792 void NumberToStringStub::Generate(MacroAssembler* masm) { |
| 4871 Register result = x0; | 4793 Register result = x0; |
| 4872 Register object = x1; | 4794 Register object = x1; |
| 4873 Label runtime; | 4795 Label runtime; |
| 4874 | 4796 |
| 4875 __ Pop(object); | 4797 __ Pop(object); |
| 4876 | 4798 |
| 4877 // Generate code to lookup number in the number string cache. | 4799 // Generate code to lookup number in the number string cache. |
| 4878 GenerateLookupNumberStringCache(masm, object, result, x2, x3, x4, &runtime); | 4800 __ LookupNumberStringCache(object, result, x2, x3, x4, &runtime); |
| 4879 __ Ret(); | 4801 __ Ret(); |
| 4880 | 4802 |
| 4881 // Handle number to string in the runtime system if not found in the cache. | 4803 // Handle number to string in the runtime system if not found in the cache. |
| 4882 __ Bind(&runtime); | 4804 __ Bind(&runtime); |
| 4883 __ Push(object); | 4805 __ Push(object); |
| 4884 __ TailCallRuntime(Runtime::kNumberToStringSkipCache, 1, 1); | 4806 __ TailCallRuntime(Runtime::kNumberToStringSkipCache, 1, 1); |
| 4885 } | 4807 } |
| 4886 | 4808 |
| 4887 | 4809 |
| 4888 void StringHelper::GenerateTwoCharacterStringTableProbe(MacroAssembler* masm, | 4810 void StringHelper::GenerateTwoCharacterStringTableProbe(MacroAssembler* masm, |
| (...skipping 994 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5883 ASSERT(!AreAliased(arg, scratch1, scratch2, scratch3, scratch4)); | 5805 ASSERT(!AreAliased(arg, scratch1, scratch2, scratch3, scratch4)); |
| 5884 | 5806 |
| 5885 // First check if the argument is already a string. | 5807 // First check if the argument is already a string. |
| 5886 Label not_string, done; | 5808 Label not_string, done; |
| 5887 __ JumpIfSmi(arg, ¬_string); | 5809 __ JumpIfSmi(arg, ¬_string); |
| 5888 __ JumpIfObjectType(arg, scratch1, scratch1, FIRST_NONSTRING_TYPE, &done, lt); | 5810 __ JumpIfObjectType(arg, scratch1, scratch1, FIRST_NONSTRING_TYPE, &done, lt); |
| 5889 | 5811 |
| 5890 // Check the number to string cache. | 5812 // Check the number to string cache. |
| 5891 __ Bind(¬_string); | 5813 __ Bind(¬_string); |
| 5892 // Puts the cache result into scratch1. | 5814 // Puts the cache result into scratch1. |
| 5893 NumberToStringStub::GenerateLookupNumberStringCache( | 5815 __ LookupNumberStringCache(arg, scratch1, scratch2, scratch3, scratch4, slow); |
| 5894 masm, | |
| 5895 arg, | |
| 5896 scratch1, | |
| 5897 scratch2, | |
| 5898 scratch3, | |
| 5899 scratch4, | |
| 5900 slow); | |
| 5901 __ Mov(arg, scratch1); | 5816 __ Mov(arg, scratch1); |
| 5902 | 5817 |
| 5903 __ Bind(&done); | 5818 __ Bind(&done); |
| 5904 } | 5819 } |
| 5905 | 5820 |
| 5906 | 5821 |
| 5907 void StringAddStub::GenerateRegisterArgsPush(MacroAssembler* masm) { | 5822 void StringAddStub::GenerateRegisterArgsPush(MacroAssembler* masm) { |
| 5908 __ Push(x0, x1); | 5823 __ Push(x0, x1); |
| 5909 } | 5824 } |
| 5910 | 5825 |
| (...skipping 1028 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6939 __ Bind(&fast_elements_case); | 6854 __ Bind(&fast_elements_case); |
| 6940 GenerateCase(masm, FAST_ELEMENTS); | 6855 GenerateCase(masm, FAST_ELEMENTS); |
| 6941 } | 6856 } |
| 6942 | 6857 |
| 6943 | 6858 |
| 6944 #undef __ | 6859 #undef __ |
| 6945 | 6860 |
| 6946 } } // namespace v8::internal | 6861 } } // namespace v8::internal |
| 6947 | 6862 |
| 6948 #endif // V8_TARGET_ARCH_A64 | 6863 #endif // V8_TARGET_ARCH_A64 |
| OLD | NEW |