Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(437)

Side by Side Diff: src/arm64/code-stubs-arm64.cc

Issue 1676883002: [runtime] Optimize and unify rest parameters. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 4 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698