OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #if V8_TARGET_ARCH_ARM | 5 #if V8_TARGET_ARCH_ARM |
6 | 6 |
7 #include "src/base/bits.h" | 7 #include "src/base/bits.h" |
8 #include "src/bootstrapper.h" | 8 #include "src/bootstrapper.h" |
9 #include "src/code-stubs.h" | 9 #include "src/code-stubs.h" |
10 #include "src/codegen.h" | 10 #include "src/codegen.h" |
(...skipping 1855 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1866 __ bind(&done); | 1866 __ bind(&done); |
1867 __ Ret(); | 1867 __ Ret(); |
1868 | 1868 |
1869 // Do the runtime call to allocate the arguments object. | 1869 // Do the runtime call to allocate the arguments object. |
1870 __ bind(&runtime); | 1870 __ bind(&runtime); |
1871 __ Push(r1, r3, r2); | 1871 __ Push(r1, r3, r2); |
1872 __ TailCallRuntime(Runtime::kNewStrictArguments); | 1872 __ TailCallRuntime(Runtime::kNewStrictArguments); |
1873 } | 1873 } |
1874 | 1874 |
1875 | 1875 |
1876 void RestParamAccessStub::GenerateNew(MacroAssembler* masm) { | |
1877 // r2 : number of parameters (tagged) | |
1878 // r3 : parameters pointer | |
1879 // r4 : rest parameter index (tagged) | |
1880 | |
1881 Label runtime; | |
1882 __ ldr(r5, MemOperand(fp, StandardFrameConstants::kCallerFPOffset)); | |
1883 __ ldr(r0, MemOperand(r5, StandardFrameConstants::kContextOffset)); | |
1884 __ cmp(r0, Operand(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR))); | |
1885 __ b(ne, &runtime); | |
1886 | |
1887 // Patch the arguments.length and the parameters pointer. | |
1888 __ ldr(r2, MemOperand(r5, ArgumentsAdaptorFrameConstants::kLengthOffset)); | |
1889 __ add(r3, r5, Operand::PointerOffsetFromSmiKey(r2)); | |
1890 __ add(r3, r3, Operand(StandardFrameConstants::kCallerSPOffset)); | |
1891 | |
1892 __ bind(&runtime); | |
1893 __ Push(r2, r3, r4); | |
1894 __ TailCallRuntime(Runtime::kNewRestParam); | |
1895 } | |
1896 | |
1897 | |
1898 void RegExpExecStub::Generate(MacroAssembler* masm) { | 1876 void RegExpExecStub::Generate(MacroAssembler* masm) { |
1899 // Just jump directly to runtime if native RegExp is not selected at compile | 1877 // Just jump directly to runtime if native RegExp is not selected at compile |
1900 // time or if regexp entry in generated code is turned off runtime switch or | 1878 // time or if regexp entry in generated code is turned off runtime switch or |
1901 // at compilation. | 1879 // at compilation. |
1902 #ifdef V8_INTERPRETED_REGEXP | 1880 #ifdef V8_INTERPRETED_REGEXP |
1903 __ TailCallRuntime(Runtime::kRegExpExec); | 1881 __ TailCallRuntime(Runtime::kRegExpExec); |
1904 #else // V8_INTERPRETED_REGEXP | 1882 #else // V8_INTERPRETED_REGEXP |
1905 | 1883 |
1906 // Stack frame on entry. | 1884 // Stack frame on entry. |
1907 // sp[0]: last_match_info (expected JSArray) | 1885 // sp[0]: last_match_info (expected JSArray) |
(...skipping 3055 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4963 Label fast_elements_case; | 4941 Label fast_elements_case; |
4964 __ cmp(r3, Operand(FAST_ELEMENTS)); | 4942 __ cmp(r3, Operand(FAST_ELEMENTS)); |
4965 __ b(eq, &fast_elements_case); | 4943 __ b(eq, &fast_elements_case); |
4966 GenerateCase(masm, FAST_HOLEY_ELEMENTS); | 4944 GenerateCase(masm, FAST_HOLEY_ELEMENTS); |
4967 | 4945 |
4968 __ bind(&fast_elements_case); | 4946 __ bind(&fast_elements_case); |
4969 GenerateCase(masm, FAST_ELEMENTS); | 4947 GenerateCase(masm, FAST_ELEMENTS); |
4970 } | 4948 } |
4971 | 4949 |
4972 | 4950 |
| 4951 void FastNewRestParameterStub::Generate(MacroAssembler* masm) { |
| 4952 // ----------- S t a t e ------------- |
| 4953 // -- r1 : function |
| 4954 // -- cp : context |
| 4955 // -- fp : frame pointer |
| 4956 // -- lr : return address |
| 4957 // ----------------------------------- |
| 4958 __ AssertFunction(r1); |
| 4959 |
| 4960 // For Ignition we need to skip all possible handler/stub frames until |
| 4961 // we reach the JavaScript frame for the function (similar to what the |
| 4962 // runtime fallback implementation does). So make r2 point to that |
| 4963 // JavaScript frame. |
| 4964 { |
| 4965 Label loop, loop_entry; |
| 4966 __ mov(r2, fp); |
| 4967 __ b(&loop_entry); |
| 4968 __ bind(&loop); |
| 4969 __ ldr(r2, MemOperand(r2, StandardFrameConstants::kCallerFPOffset)); |
| 4970 __ bind(&loop_entry); |
| 4971 __ ldr(ip, MemOperand(r2, StandardFrameConstants::kMarkerOffset)); |
| 4972 __ cmp(ip, r1); |
| 4973 __ b(ne, &loop); |
| 4974 } |
| 4975 |
| 4976 // Check if we have rest parameters (only possible if we have an |
| 4977 // arguments adaptor frame below the function frame). |
| 4978 Label no_rest_parameters; |
| 4979 __ ldr(r2, MemOperand(r2, StandardFrameConstants::kCallerFPOffset)); |
| 4980 __ ldr(ip, MemOperand(r2, StandardFrameConstants::kContextOffset)); |
| 4981 __ cmp(ip, Operand(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR))); |
| 4982 __ b(ne, &no_rest_parameters); |
| 4983 |
| 4984 // Check if the arguments adaptor frame contains more arguments than |
| 4985 // specified by the function's internal formal parameter count. |
| 4986 Label rest_parameters; |
| 4987 __ ldr(r0, MemOperand(r2, ArgumentsAdaptorFrameConstants::kLengthOffset)); |
| 4988 __ ldr(r1, FieldMemOperand(r1, JSFunction::kSharedFunctionInfoOffset)); |
| 4989 __ ldr(r1, |
| 4990 FieldMemOperand(r1, SharedFunctionInfo::kFormalParameterCountOffset)); |
| 4991 __ sub(r0, r0, r1, SetCC); |
| 4992 __ b(gt, &rest_parameters); |
| 4993 |
| 4994 // Return an empty rest parameter array. |
| 4995 __ bind(&no_rest_parameters); |
| 4996 { |
| 4997 // ----------- S t a t e ------------- |
| 4998 // -- cp : context |
| 4999 // -- lr : return address |
| 5000 // ----------------------------------- |
| 5001 |
| 5002 // Allocate an empty rest parameter array. |
| 5003 Label allocate, done_allocate; |
| 5004 __ Allocate(JSArray::kSize, r0, r1, r2, &allocate, TAG_OBJECT); |
| 5005 __ bind(&done_allocate); |
| 5006 |
| 5007 // Setup the rest parameter array in r0. |
| 5008 __ LoadNativeContextSlot(Context::JS_ARRAY_FAST_ELEMENTS_MAP_INDEX, r1); |
| 5009 __ str(r1, FieldMemOperand(r0, JSArray::kMapOffset)); |
| 5010 __ LoadRoot(r1, Heap::kEmptyFixedArrayRootIndex); |
| 5011 __ str(r1, FieldMemOperand(r0, JSArray::kPropertiesOffset)); |
| 5012 __ str(r1, FieldMemOperand(r0, JSArray::kElementsOffset)); |
| 5013 __ mov(r1, Operand(0)); |
| 5014 __ str(r1, FieldMemOperand(r0, JSArray::kLengthOffset)); |
| 5015 STATIC_ASSERT(JSArray::kSize == 4 * kPointerSize); |
| 5016 __ Ret(); |
| 5017 |
| 5018 // Fall back to %AllocateInNewSpace. |
| 5019 __ bind(&allocate); |
| 5020 { |
| 5021 FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL); |
| 5022 __ Push(Smi::FromInt(JSArray::kSize)); |
| 5023 __ CallRuntime(Runtime::kAllocateInNewSpace); |
| 5024 } |
| 5025 __ jmp(&done_allocate); |
| 5026 } |
| 5027 |
| 5028 __ bind(&rest_parameters); |
| 5029 { |
| 5030 // Compute the pointer to the first rest parameter (skippping the receiver). |
| 5031 __ add(r2, r2, Operand(r0, LSL, kPointerSizeLog2 - 1)); |
| 5032 __ add(r2, r2, |
| 5033 Operand(StandardFrameConstants::kCallerSPOffset - 1 * kPointerSize)); |
| 5034 |
| 5035 // ----------- S t a t e ------------- |
| 5036 // -- cp : context |
| 5037 // -- r0 : number of rest parameters (tagged) |
| 5038 // -- r2 : pointer to first rest parameters |
| 5039 // -- lr : return address |
| 5040 // ----------------------------------- |
| 5041 |
| 5042 // Allocate space for the rest parameter array plus the backing store. |
| 5043 Label allocate, done_allocate; |
| 5044 __ mov(r1, Operand(JSArray::kSize + FixedArray::kHeaderSize)); |
| 5045 __ add(r1, r1, Operand(r0, LSL, kPointerSizeLog2 - 1)); |
| 5046 __ Allocate(r1, r3, r4, r5, &allocate, TAG_OBJECT); |
| 5047 __ bind(&done_allocate); |
| 5048 |
| 5049 // Setup the elements array in r3. |
| 5050 __ LoadRoot(r1, Heap::kFixedArrayMapRootIndex); |
| 5051 __ str(r1, FieldMemOperand(r3, FixedArray::kMapOffset)); |
| 5052 __ str(r0, FieldMemOperand(r3, FixedArray::kLengthOffset)); |
| 5053 __ add(r4, r3, Operand(FixedArray::kHeaderSize)); |
| 5054 { |
| 5055 Label loop, done_loop; |
| 5056 __ add(r1, r4, Operand(r0, LSL, kPointerSizeLog2 - 1)); |
| 5057 __ bind(&loop); |
| 5058 __ cmp(r4, r1); |
| 5059 __ b(eq, &done_loop); |
| 5060 __ ldr(ip, MemOperand(r2, 1 * kPointerSize, NegPostIndex)); |
| 5061 __ str(ip, FieldMemOperand(r4, 0 * kPointerSize)); |
| 5062 __ add(r4, r4, Operand(1 * kPointerSize)); |
| 5063 __ b(&loop); |
| 5064 __ bind(&done_loop); |
| 5065 } |
| 5066 |
| 5067 // Setup the rest parameter array in r4. |
| 5068 __ LoadNativeContextSlot(Context::JS_ARRAY_FAST_ELEMENTS_MAP_INDEX, r1); |
| 5069 __ str(r1, FieldMemOperand(r4, JSArray::kMapOffset)); |
| 5070 __ LoadRoot(r1, Heap::kEmptyFixedArrayRootIndex); |
| 5071 __ str(r1, FieldMemOperand(r4, JSArray::kPropertiesOffset)); |
| 5072 __ str(r3, FieldMemOperand(r4, JSArray::kElementsOffset)); |
| 5073 __ str(r0, FieldMemOperand(r4, JSArray::kLengthOffset)); |
| 5074 STATIC_ASSERT(JSArray::kSize == 4 * kPointerSize); |
| 5075 __ mov(r0, r4); |
| 5076 __ Ret(); |
| 5077 |
| 5078 // Fall back to %AllocateInNewSpace. |
| 5079 __ bind(&allocate); |
| 5080 { |
| 5081 FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL); |
| 5082 __ SmiTag(r1); |
| 5083 __ Push(r0, r2, r1); |
| 5084 __ CallRuntime(Runtime::kAllocateInNewSpace); |
| 5085 __ mov(r3, r0); |
| 5086 __ Pop(r0, r2); |
| 5087 } |
| 5088 __ jmp(&done_allocate); |
| 5089 } |
| 5090 } |
| 5091 |
| 5092 |
4973 void LoadGlobalViaContextStub::Generate(MacroAssembler* masm) { | 5093 void LoadGlobalViaContextStub::Generate(MacroAssembler* masm) { |
4974 Register context = cp; | 5094 Register context = cp; |
4975 Register result = r0; | 5095 Register result = r0; |
4976 Register slot = r2; | 5096 Register slot = r2; |
4977 | 5097 |
4978 // Go up the context chain to the script context. | 5098 // Go up the context chain to the script context. |
4979 for (int i = 0; i < depth(); ++i) { | 5099 for (int i = 0; i < depth(); ++i) { |
4980 __ ldr(result, ContextMemOperand(context, Context::PREVIOUS_INDEX)); | 5100 __ ldr(result, ContextMemOperand(context, Context::PREVIOUS_INDEX)); |
4981 context = result; | 5101 context = result; |
4982 } | 5102 } |
(...skipping 458 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5441 kStackUnwindSpace, NULL, return_value_operand, NULL); | 5561 kStackUnwindSpace, NULL, return_value_operand, NULL); |
5442 } | 5562 } |
5443 | 5563 |
5444 | 5564 |
5445 #undef __ | 5565 #undef __ |
5446 | 5566 |
5447 } // namespace internal | 5567 } // namespace internal |
5448 } // namespace v8 | 5568 } // namespace v8 |
5449 | 5569 |
5450 #endif // V8_TARGET_ARCH_ARM | 5570 #endif // V8_TARGET_ARCH_ARM |
OLD | NEW |