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

Side by Side Diff: src/builtins/ia32/builtins-ia32.cc

Issue 2890023004: [turbofan] Avoid allocating rest parameters for spread calls. (Closed)
Patch Set: Created 3 years, 7 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
« no previous file with comments | « src/builtins/builtins-definitions.h ('k') | src/builtins/mips/builtins-mips.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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_IA32 5 #if V8_TARGET_ARCH_IA32
6 6
7 #include "src/code-factory.h" 7 #include "src/code-factory.h"
8 #include "src/codegen.h" 8 #include "src/codegen.h"
9 #include "src/deoptimizer.h" 9 #include "src/deoptimizer.h"
10 #include "src/full-codegen/full-codegen.h" 10 #include "src/full-codegen/full-codegen.h"
(...skipping 2291 matching lines...) Expand 10 before | Expand all | Expand 10 after
2302 2302
2303 // Dispatch to Call or Construct depending on whether new.target is undefined. 2303 // Dispatch to Call or Construct depending on whether new.target is undefined.
2304 { 2304 {
2305 __ CompareRoot(edx, Heap::kUndefinedValueRootIndex); 2305 __ CompareRoot(edx, Heap::kUndefinedValueRootIndex);
2306 __ j(equal, masm->isolate()->builtins()->Call(), RelocInfo::CODE_TARGET); 2306 __ j(equal, masm->isolate()->builtins()->Call(), RelocInfo::CODE_TARGET);
2307 __ Jump(masm->isolate()->builtins()->Construct(), RelocInfo::CODE_TARGET); 2307 __ Jump(masm->isolate()->builtins()->Construct(), RelocInfo::CODE_TARGET);
2308 } 2308 }
2309 } 2309 }
2310 2310
2311 // static 2311 // static
2312 void Builtins::Generate_CallForwardVarargs(MacroAssembler* masm, 2312 void Builtins::Generate_ForwardVarargs(MacroAssembler* masm,
2313 Handle<Code> code) { 2313 Handle<Code> code) {
2314 // ----------- S t a t e ------------- 2314 // ----------- S t a t e -------------
2315 // -- edi : the target to call (can be any Object) 2315 // -- eax : the number of arguments (not including the receiver)
2316 // -- ecx : start index (to support rest parameters) 2316 // -- edi : the target to call (can be any Object)
2317 // -- esp[0] : return address. 2317 // -- edx : the new target (for [[Construct]] calls)
2318 // -- esp[4] : thisArgument 2318 // -- ecx : start index (to support rest parameters)
2319 // ----------------------------------- 2319 // -----------------------------------
2320 2320
2321 // Preserve new.target (in case of [[Construct]]).
2322 __ movd(xmm0, edx);
2323
2321 // Check if we have an arguments adaptor frame below the function frame. 2324 // Check if we have an arguments adaptor frame below the function frame.
2322 Label arguments_adaptor, arguments_done; 2325 Label arguments_adaptor, arguments_done;
2323 __ mov(ebx, Operand(ebp, StandardFrameConstants::kCallerFPOffset)); 2326 __ mov(ebx, Operand(ebp, StandardFrameConstants::kCallerFPOffset));
2324 __ cmp(Operand(ebx, CommonFrameConstants::kContextOrFrameTypeOffset), 2327 __ cmp(Operand(ebx, CommonFrameConstants::kContextOrFrameTypeOffset),
2325 Immediate(StackFrame::TypeToMarker(StackFrame::ARGUMENTS_ADAPTOR))); 2328 Immediate(StackFrame::TypeToMarker(StackFrame::ARGUMENTS_ADAPTOR)));
2326 __ j(equal, &arguments_adaptor, Label::kNear); 2329 __ j(equal, &arguments_adaptor, Label::kNear);
2327 { 2330 {
2328 __ mov(eax, Operand(ebp, JavaScriptFrameConstants::kFunctionOffset)); 2331 __ mov(edx, Operand(ebp, JavaScriptFrameConstants::kFunctionOffset));
2329 __ mov(eax, FieldOperand(eax, JSFunction::kSharedFunctionInfoOffset)); 2332 __ mov(edx, FieldOperand(edx, JSFunction::kSharedFunctionInfoOffset));
2330 __ mov(eax, 2333 __ mov(edx,
2331 FieldOperand(eax, SharedFunctionInfo::kFormalParameterCountOffset)); 2334 FieldOperand(edx, SharedFunctionInfo::kFormalParameterCountOffset));
2332 __ mov(ebx, ebp); 2335 __ mov(ebx, ebp);
2333 } 2336 }
2334 __ jmp(&arguments_done, Label::kNear); 2337 __ jmp(&arguments_done, Label::kNear);
2335 __ bind(&arguments_adaptor); 2338 __ bind(&arguments_adaptor);
2336 { 2339 {
2337 // Just load the length from the ArgumentsAdaptorFrame. 2340 // Just load the length from the ArgumentsAdaptorFrame.
2338 __ mov(eax, Operand(ebx, ArgumentsAdaptorFrameConstants::kLengthOffset)); 2341 __ mov(edx, Operand(ebx, ArgumentsAdaptorFrameConstants::kLengthOffset));
2339 } 2342 }
2340 __ bind(&arguments_done); 2343 __ bind(&arguments_done);
2341 2344
2342 Label stack_empty, stack_done; 2345 Label stack_done;
2343 __ SmiUntag(eax); 2346 __ SmiUntag(edx);
2344 __ sub(eax, ecx); 2347 __ sub(edx, ecx);
2345 __ j(less_equal, &stack_empty); 2348 __ j(less_equal, &stack_done);
2346 { 2349 {
2347 // Check for stack overflow. 2350 // Check for stack overflow.
2348 { 2351 {
2349 // Check the stack for overflow. We are not trying to catch interruptions 2352 // Check the stack for overflow. We are not trying to catch interruptions
2350 // (i.e. debug break and preemption) here, so check the "real stack 2353 // (i.e. debug break and preemption) here, so check the "real stack
2351 // limit". 2354 // limit".
2352 Label done; 2355 Label done;
2353 __ LoadRoot(ecx, Heap::kRealStackLimitRootIndex); 2356 __ LoadRoot(ecx, Heap::kRealStackLimitRootIndex);
2354 // Make ecx the space we have left. The stack might already be 2357 // Make ecx the space we have left. The stack might already be
2355 // overflowed here which will cause ecx to become negative. 2358 // overflowed here which will cause ecx to become negative.
2356 __ neg(ecx); 2359 __ neg(ecx);
2357 __ add(ecx, esp); 2360 __ add(ecx, esp);
2358 __ sar(ecx, kPointerSizeLog2); 2361 __ sar(ecx, kPointerSizeLog2);
2359 // Check if the arguments will overflow the stack. 2362 // Check if the arguments will overflow the stack.
2360 __ cmp(ecx, eax); 2363 __ cmp(ecx, edx);
2361 __ j(greater, &done, Label::kNear); // Signed comparison. 2364 __ j(greater, &done, Label::kNear); // Signed comparison.
2362 __ TailCallRuntime(Runtime::kThrowStackOverflow); 2365 __ TailCallRuntime(Runtime::kThrowStackOverflow);
2363 __ bind(&done); 2366 __ bind(&done);
2364 } 2367 }
2365 2368
2366 // Forward the arguments from the caller frame. 2369 // Forward the arguments from the caller frame.
2367 { 2370 {
2368 Label loop; 2371 Label loop;
2369 __ mov(ecx, eax); 2372 __ add(eax, edx);
2370 __ pop(edx); 2373 __ PopReturnAddressTo(ecx);
2371 __ bind(&loop); 2374 __ bind(&loop);
2372 { 2375 {
2373 __ Push(Operand(ebx, ecx, times_pointer_size, 1 * kPointerSize)); 2376 __ Push(Operand(ebx, edx, times_pointer_size, 1 * kPointerSize));
2374 __ dec(ecx); 2377 __ dec(edx);
2375 __ j(not_zero, &loop); 2378 __ j(not_zero, &loop);
2376 } 2379 }
2377 __ push(edx); 2380 __ PushReturnAddressFrom(ecx);
2378 } 2381 }
2379 } 2382 }
2380 __ jmp(&stack_done, Label::kNear);
2381 __ bind(&stack_empty);
2382 {
2383 // We just pass the receiver, which is already on the stack.
2384 __ Move(eax, Immediate(0));
2385 }
2386 __ bind(&stack_done); 2383 __ bind(&stack_done);
2387 2384
2385 // Restore new.target (in case of [[Construct]]).
2386 __ movd(edx, xmm0);
2387
2388 // Tail-call to the {code} handler.
2388 __ Jump(code, RelocInfo::CODE_TARGET); 2389 __ Jump(code, RelocInfo::CODE_TARGET);
2389 } 2390 }
2390 2391
2391 namespace { 2392 namespace {
2392 2393
2393 // Drops top JavaScript frame and an arguments adaptor frame below it (if 2394 // Drops top JavaScript frame and an arguments adaptor frame below it (if
2394 // present) preserving all the arguments prepared for current call. 2395 // present) preserving all the arguments prepared for current call.
2395 // Does nothing if debugger is currently active. 2396 // Does nothing if debugger is currently active.
2396 // ES6 14.6.3. PrepareForTailCall 2397 // ES6 14.6.3. PrepareForTailCall
2397 // 2398 //
(...skipping 926 matching lines...) Expand 10 before | Expand all | Expand 10 after
3324 } 3325 }
3325 // Now jump to the instructions of the returned code object. 3326 // Now jump to the instructions of the returned code object.
3326 __ jmp(edi); 3327 __ jmp(edi);
3327 } 3328 }
3328 3329
3329 #undef __ 3330 #undef __
3330 } // namespace internal 3331 } // namespace internal
3331 } // namespace v8 3332 } // namespace v8
3332 3333
3333 #endif // V8_TARGET_ARCH_IA32 3334 #endif // V8_TARGET_ARCH_IA32
OLDNEW
« no previous file with comments | « src/builtins/builtins-definitions.h ('k') | src/builtins/mips/builtins-mips.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698