OLD | NEW |
1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 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_ARM64 | 5 #if V8_TARGET_ARCH_ARM64 |
6 | 6 |
7 #include "src/bootstrapper.h" | 7 #include "src/bootstrapper.h" |
8 #include "src/code-stubs.h" | 8 #include "src/code-stubs.h" |
9 #include "src/codegen.h" | 9 #include "src/codegen.h" |
10 #include "src/ic/handler-compiler.h" | 10 #include "src/ic/handler-compiler.h" |
(...skipping 2118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2129 __ Bind(&done); | 2129 __ Bind(&done); |
2130 __ Ret(); | 2130 __ Ret(); |
2131 | 2131 |
2132 // Do the runtime call to allocate the arguments object. | 2132 // Do the runtime call to allocate the arguments object. |
2133 __ Bind(&runtime); | 2133 __ Bind(&runtime); |
2134 __ Push(function, params, param_count_smi); | 2134 __ Push(function, params, param_count_smi); |
2135 __ TailCallRuntime(Runtime::kNewStrictArguments); | 2135 __ TailCallRuntime(Runtime::kNewStrictArguments); |
2136 } | 2136 } |
2137 | 2137 |
2138 | 2138 |
2139 void RestParamAccessStub::GenerateNew(MacroAssembler* masm) { | |
2140 // x2 : number of parameters (tagged) | |
2141 // x3 : parameters pointer | |
2142 // x4 : rest parameter index (tagged) | |
2143 // | |
2144 // Returns pointer to result object in x0. | |
2145 | |
2146 DCHECK(x2.is(ArgumentsAccessNewDescriptor::parameter_count())); | |
2147 DCHECK(x3.is(RestParamAccessDescriptor::parameter_pointer())); | |
2148 DCHECK(x4.is(RestParamAccessDescriptor::rest_parameter_index())); | |
2149 | |
2150 // Get the stub arguments from the frame, and make an untagged copy of the | |
2151 // parameter count. | |
2152 Register rest_index_smi = x4; | |
2153 Register param_count_smi = x2; | |
2154 Register params = x3; | |
2155 Register param_count = x13; | |
2156 __ SmiUntag(param_count, param_count_smi); | |
2157 | |
2158 // Test if arguments adaptor needed. | |
2159 Register caller_fp = x11; | |
2160 Register caller_ctx = x12; | |
2161 Label runtime; | |
2162 __ Ldr(caller_fp, MemOperand(fp, StandardFrameConstants::kCallerFPOffset)); | |
2163 __ Ldr(caller_ctx, | |
2164 MemOperand(caller_fp, StandardFrameConstants::kContextOffset)); | |
2165 __ Cmp(caller_ctx, Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR)); | |
2166 __ B(ne, &runtime); | |
2167 | |
2168 // x4 rest_index_smi index of rest parameter | |
2169 // x2 param_count_smi number of parameters passed to function (smi) | |
2170 // x3 params pointer to parameters | |
2171 // x11 caller_fp caller's frame pointer | |
2172 // x13 param_count number of parameters passed to function | |
2173 | |
2174 // Patch the argument length and parameters pointer. | |
2175 __ Ldr(param_count_smi, | |
2176 MemOperand(caller_fp, ArgumentsAdaptorFrameConstants::kLengthOffset)); | |
2177 __ SmiUntag(param_count, param_count_smi); | |
2178 __ Add(x10, caller_fp, Operand(param_count, LSL, kPointerSizeLog2)); | |
2179 __ Add(params, x10, StandardFrameConstants::kCallerSPOffset); | |
2180 | |
2181 __ Bind(&runtime); | |
2182 __ Push(param_count_smi, params, rest_index_smi); | |
2183 __ TailCallRuntime(Runtime::kNewRestParam); | |
2184 } | |
2185 | |
2186 | |
2187 void RegExpExecStub::Generate(MacroAssembler* masm) { | 2139 void RegExpExecStub::Generate(MacroAssembler* masm) { |
2188 #ifdef V8_INTERPRETED_REGEXP | 2140 #ifdef V8_INTERPRETED_REGEXP |
2189 __ TailCallRuntime(Runtime::kRegExpExec); | 2141 __ TailCallRuntime(Runtime::kRegExpExec); |
2190 #else // V8_INTERPRETED_REGEXP | 2142 #else // V8_INTERPRETED_REGEXP |
2191 | 2143 |
2192 // Stack frame on entry. | 2144 // Stack frame on entry. |
2193 // jssp[0]: last_match_info (expected JSArray) | 2145 // jssp[0]: last_match_info (expected JSArray) |
2194 // jssp[8]: previous index | 2146 // jssp[8]: previous index |
2195 // jssp[16]: subject string | 2147 // jssp[16]: subject string |
2196 // jssp[24]: JSRegExp object | 2148 // jssp[24]: JSRegExp object |
(...skipping 3188 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5385 | 5337 |
5386 Label fast_elements_case; | 5338 Label fast_elements_case; |
5387 __ CompareAndBranch(kind, FAST_ELEMENTS, eq, &fast_elements_case); | 5339 __ CompareAndBranch(kind, FAST_ELEMENTS, eq, &fast_elements_case); |
5388 GenerateCase(masm, FAST_HOLEY_ELEMENTS); | 5340 GenerateCase(masm, FAST_HOLEY_ELEMENTS); |
5389 | 5341 |
5390 __ Bind(&fast_elements_case); | 5342 __ Bind(&fast_elements_case); |
5391 GenerateCase(masm, FAST_ELEMENTS); | 5343 GenerateCase(masm, FAST_ELEMENTS); |
5392 } | 5344 } |
5393 | 5345 |
5394 | 5346 |
| 5347 void FastNewRestParameterStub::Generate(MacroAssembler* masm) { |
| 5348 // ----------- S t a t e ------------- |
| 5349 // -- x1 : function |
| 5350 // -- cp : context |
| 5351 // -- fp : frame pointer |
| 5352 // -- lr : return address |
| 5353 // ----------------------------------- |
| 5354 __ AssertFunction(x1); |
| 5355 |
| 5356 // For Ignition we need to skip all possible handler/stub frames until |
| 5357 // we reach the JavaScript frame for the function (similar to what the |
| 5358 // runtime fallback implementation does). So make x2 point to that |
| 5359 // JavaScript frame. |
| 5360 { |
| 5361 Label loop, loop_entry; |
| 5362 __ Mov(x2, fp); |
| 5363 __ B(&loop_entry); |
| 5364 __ Bind(&loop); |
| 5365 __ Ldr(x2, MemOperand(x2, StandardFrameConstants::kCallerFPOffset)); |
| 5366 __ Bind(&loop_entry); |
| 5367 __ Ldr(x3, MemOperand(x2, StandardFrameConstants::kMarkerOffset)); |
| 5368 __ Cmp(x3, x1); |
| 5369 __ B(ne, &loop); |
| 5370 } |
| 5371 |
| 5372 // Check if we have rest parameters (only possible if we have an |
| 5373 // arguments adaptor frame below the function frame). |
| 5374 Label no_rest_parameters; |
| 5375 __ Ldr(x2, MemOperand(x2, StandardFrameConstants::kCallerFPOffset)); |
| 5376 __ Ldr(x3, MemOperand(x2, StandardFrameConstants::kContextOffset)); |
| 5377 __ Cmp(x3, Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR)); |
| 5378 __ B(ne, &no_rest_parameters); |
| 5379 |
| 5380 // Check if the arguments adaptor frame contains more arguments than |
| 5381 // specified by the function's internal formal parameter count. |
| 5382 Label rest_parameters; |
| 5383 __ Ldrsw(x0, UntagSmiMemOperand( |
| 5384 x2, ArgumentsAdaptorFrameConstants::kLengthOffset)); |
| 5385 __ Ldr(x1, FieldMemOperand(x1, JSFunction::kSharedFunctionInfoOffset)); |
| 5386 __ Ldrsw( |
| 5387 x1, FieldMemOperand(x1, SharedFunctionInfo::kFormalParameterCountOffset)); |
| 5388 __ Subs(x0, x0, x1); |
| 5389 __ B(gt, &rest_parameters); |
| 5390 |
| 5391 // Return an empty rest parameter array. |
| 5392 __ Bind(&no_rest_parameters); |
| 5393 { |
| 5394 // ----------- S t a t e ------------- |
| 5395 // -- cp : context |
| 5396 // -- lr : return address |
| 5397 // ----------------------------------- |
| 5398 |
| 5399 // Allocate an empty rest parameter array. |
| 5400 Label allocate, done_allocate; |
| 5401 __ Allocate(JSArray::kSize, x0, x1, x2, &allocate, TAG_OBJECT); |
| 5402 __ Bind(&done_allocate); |
| 5403 |
| 5404 // Setup the rest parameter array in x0. |
| 5405 __ LoadNativeContextSlot(Context::JS_ARRAY_FAST_ELEMENTS_MAP_INDEX, x1); |
| 5406 __ Str(x1, FieldMemOperand(x0, JSArray::kMapOffset)); |
| 5407 __ LoadRoot(x1, Heap::kEmptyFixedArrayRootIndex); |
| 5408 __ Str(x1, FieldMemOperand(x0, JSArray::kPropertiesOffset)); |
| 5409 __ Str(x1, FieldMemOperand(x0, JSArray::kElementsOffset)); |
| 5410 __ Mov(x1, Smi::FromInt(0)); |
| 5411 __ Str(x1, FieldMemOperand(x0, JSArray::kLengthOffset)); |
| 5412 STATIC_ASSERT(JSArray::kSize == 4 * kPointerSize); |
| 5413 __ Ret(); |
| 5414 |
| 5415 // Fall back to %AllocateInNewSpace. |
| 5416 __ Bind(&allocate); |
| 5417 { |
| 5418 FrameScope scope(masm, StackFrame::INTERNAL); |
| 5419 __ Push(Smi::FromInt(JSArray::kSize)); |
| 5420 __ CallRuntime(Runtime::kAllocateInNewSpace); |
| 5421 } |
| 5422 __ B(&done_allocate); |
| 5423 } |
| 5424 |
| 5425 __ Bind(&rest_parameters); |
| 5426 { |
| 5427 // Compute the pointer to the first rest parameter (skippping the receiver). |
| 5428 __ Add(x2, x2, Operand(x0, LSL, kPointerSizeLog2)); |
| 5429 __ Add(x2, x2, StandardFrameConstants::kCallerSPOffset - 1 * kPointerSize); |
| 5430 |
| 5431 // ----------- S t a t e ------------- |
| 5432 // -- cp : context |
| 5433 // -- x0 : number of rest parameters |
| 5434 // -- x2 : pointer to first rest parameters |
| 5435 // -- lr : return address |
| 5436 // ----------------------------------- |
| 5437 |
| 5438 // Allocate space for the rest parameter array plus the backing store. |
| 5439 Label allocate, done_allocate; |
| 5440 __ Mov(x1, JSArray::kSize + FixedArray::kHeaderSize); |
| 5441 __ Add(x1, x1, Operand(x0, LSL, kPointerSizeLog2)); |
| 5442 __ Allocate(x1, x3, x4, x5, &allocate, TAG_OBJECT); |
| 5443 __ Bind(&done_allocate); |
| 5444 |
| 5445 // Compute arguments.length in x6. |
| 5446 __ SmiTag(x6, x0); |
| 5447 |
| 5448 // Setup the elements array in x3. |
| 5449 __ LoadRoot(x1, Heap::kFixedArrayMapRootIndex); |
| 5450 __ Str(x1, FieldMemOperand(x3, FixedArray::kMapOffset)); |
| 5451 __ Str(x6, FieldMemOperand(x3, FixedArray::kLengthOffset)); |
| 5452 __ Add(x4, x3, FixedArray::kHeaderSize); |
| 5453 { |
| 5454 Label loop, done_loop; |
| 5455 __ Add(x0, x4, Operand(x0, LSL, kPointerSizeLog2)); |
| 5456 __ Bind(&loop); |
| 5457 __ Cmp(x4, x0); |
| 5458 __ B(eq, &done_loop); |
| 5459 __ Ldr(x5, MemOperand(x2, 0 * kPointerSize)); |
| 5460 __ Str(x5, FieldMemOperand(x4, 0 * kPointerSize)); |
| 5461 __ Sub(x2, x2, Operand(1 * kPointerSize)); |
| 5462 __ Add(x4, x4, Operand(1 * kPointerSize)); |
| 5463 __ B(&loop); |
| 5464 __ Bind(&done_loop); |
| 5465 } |
| 5466 |
| 5467 // Setup the rest parameter array in x0. |
| 5468 __ LoadNativeContextSlot(Context::JS_ARRAY_FAST_ELEMENTS_MAP_INDEX, x1); |
| 5469 __ Str(x1, FieldMemOperand(x0, JSArray::kMapOffset)); |
| 5470 __ LoadRoot(x1, Heap::kEmptyFixedArrayRootIndex); |
| 5471 __ Str(x1, FieldMemOperand(x0, JSArray::kPropertiesOffset)); |
| 5472 __ Str(x3, FieldMemOperand(x0, JSArray::kElementsOffset)); |
| 5473 __ Str(x6, FieldMemOperand(x0, JSArray::kLengthOffset)); |
| 5474 STATIC_ASSERT(JSArray::kSize == 4 * kPointerSize); |
| 5475 __ Ret(); |
| 5476 |
| 5477 // Fall back to %AllocateInNewSpace. |
| 5478 __ Bind(&allocate); |
| 5479 { |
| 5480 FrameScope scope(masm, StackFrame::INTERNAL); |
| 5481 __ SmiTag(x0); |
| 5482 __ SmiTag(x1); |
| 5483 __ Push(x0, x2, x1); |
| 5484 __ CallRuntime(Runtime::kAllocateInNewSpace); |
| 5485 __ Mov(x3, x0); |
| 5486 __ Pop(x2, x0); |
| 5487 __ SmiUntag(x0); |
| 5488 } |
| 5489 __ B(&done_allocate); |
| 5490 } |
| 5491 } |
| 5492 |
| 5493 |
5395 void LoadGlobalViaContextStub::Generate(MacroAssembler* masm) { | 5494 void LoadGlobalViaContextStub::Generate(MacroAssembler* masm) { |
5396 Register context = cp; | 5495 Register context = cp; |
5397 Register result = x0; | 5496 Register result = x0; |
5398 Register slot = x2; | 5497 Register slot = x2; |
5399 Label slow_case; | 5498 Label slow_case; |
5400 | 5499 |
5401 // Go up the context chain to the script context. | 5500 // Go up the context chain to the script context. |
5402 for (int i = 0; i < depth(); ++i) { | 5501 for (int i = 0; i < depth(); ++i) { |
5403 __ Ldr(result, ContextMemOperand(context, Context::PREVIOUS_INDEX)); | 5502 __ Ldr(result, ContextMemOperand(context, Context::PREVIOUS_INDEX)); |
5404 context = result; | 5503 context = result; |
(...skipping 485 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5890 return_value_operand, NULL); | 5989 return_value_operand, NULL); |
5891 } | 5990 } |
5892 | 5991 |
5893 | 5992 |
5894 #undef __ | 5993 #undef __ |
5895 | 5994 |
5896 } // namespace internal | 5995 } // namespace internal |
5897 } // namespace v8 | 5996 } // namespace v8 |
5898 | 5997 |
5899 #endif // V8_TARGET_ARCH_ARM64 | 5998 #endif // V8_TARGET_ARCH_ARM64 |
OLD | NEW |