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

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

Issue 1083193005: WIP: new.target (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Fix return from new func Created 5 years, 8 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/scopes.cc ('k') | src/x64/full-codegen-x64.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 #include "src/v8.h" 5 #include "src/v8.h"
6 6
7 #if V8_TARGET_ARCH_X64 7 #if V8_TARGET_ARCH_X64
8 8
9 #include "src/code-factory.h" 9 #include "src/code-factory.h"
10 #include "src/codegen.h" 10 #include "src/codegen.h"
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after
129 if (create_memento) { 129 if (create_memento) {
130 __ jmp(count_incremented); 130 __ jmp(count_incremented);
131 } else { 131 } else {
132 __ jmp(allocated); 132 __ jmp(allocated);
133 } 133 }
134 } 134 }
135 135
136 136
137 static void Generate_JSConstructStubHelper(MacroAssembler* masm, 137 static void Generate_JSConstructStubHelper(MacroAssembler* masm,
138 bool is_api_function, 138 bool is_api_function,
139 bool use_new_target,
139 bool create_memento) { 140 bool create_memento) {
140 // ----------- S t a t e ------------- 141 // ----------- S t a t e -------------
141 // -- rax: number of arguments 142 // -- rax: number of arguments
142 // -- rdi: constructor function 143 // -- rdi: constructor function
143 // -- rbx: allocation site or undefined 144 // -- rbx: allocation site or undefined
144 // -- rdx: original constructor 145 // -- rdx: original constructor
145 // ----------------------------------- 146 // -----------------------------------
146 147
147 // Should never create mementos for api functions. 148 // Should never create mementos for api functions.
148 DCHECK(!is_api_function || !create_memento); 149 DCHECK(!is_api_function || !create_memento);
149 150
150 // Enter a construct frame. 151 // Enter a construct frame.
151 { 152 {
152 FrameScope scope(masm, StackFrame::CONSTRUCT); 153 FrameScope scope(masm, StackFrame::CONSTRUCT);
153 154
154 if (create_memento) { 155 if (create_memento) {
155 __ AssertUndefinedOrAllocationSite(rbx); 156 __ AssertUndefinedOrAllocationSite(rbx);
156 __ Push(rbx); 157 __ Push(rbx);
157 } 158 }
158 159
159 // Store a smi-tagged arguments count on the stack. 160 // Store a smi-tagged arguments count on the stack.
160 __ Integer32ToSmi(rax, rax); 161 __ Integer32ToSmi(rax, rax);
161 __ Push(rax); 162 __ Push(rax);
162 163
163 // Push the function to invoke on the stack. 164 // Push the function to invoke on the stack.
165
166 if (use_new_target) {
167 __ Push(rdx);
168 }
164 __ Push(rdi); 169 __ Push(rdi);
165 170
166 Label rt_call, normal_new, allocated, count_incremented; 171 Label rt_call, normal_new, allocated, count_incremented;
167 __ cmpp(rdx, rdi); 172 __ cmpp(rdx, rdi);
168 __ j(equal, &normal_new); 173 __ j(equal, &normal_new);
169 174
170 Generate_Runtime_NewObject(masm, create_memento, rdx, &count_incremented, 175 Generate_Runtime_NewObject(masm, create_memento, rdx, &count_incremented,
171 &allocated); 176 &allocated);
172 177
173 __ bind(&normal_new); 178 __ bind(&normal_new);
(...skipping 228 matching lines...) Expand 10 before | Expand all | Expand 10 after
402 // rcx is an AllocationSite. We are creating a memento from it, so we 407 // rcx is an AllocationSite. We are creating a memento from it, so we
403 // need to increment the memento create count. 408 // need to increment the memento create count.
404 __ SmiAddConstant( 409 __ SmiAddConstant(
405 FieldOperand(rcx, AllocationSite::kPretenureCreateCountOffset), 410 FieldOperand(rcx, AllocationSite::kPretenureCreateCountOffset),
406 Smi::FromInt(1)); 411 Smi::FromInt(1));
407 __ bind(&count_incremented); 412 __ bind(&count_incremented);
408 } 413 }
409 414
410 // Retrieve the function from the stack. 415 // Retrieve the function from the stack.
411 __ Pop(rdi); 416 __ Pop(rdi);
417 if (use_new_target) {
418 __ Pop(rdx);
419 }
412 420
413 // Retrieve smi-tagged arguments count from the stack. 421 // Retrieve smi-tagged arguments count from the stack.
414 __ movp(rax, Operand(rsp, 0)); 422 __ movp(rax, Operand(rsp, 0));
415 __ SmiToInteger32(rax, rax); 423 __ SmiToInteger32(rax, rax);
416 424
417 // Push the allocated receiver to the stack. We need two copies 425 // Push the allocated receiver to the stack. We need two copies
418 // because we may have to return the original one and the calling 426 // because we may have to return the original one and the calling
419 // conventions dictate that the called function pops the receiver. 427 // conventions dictate that the called function pops the receiver.
420 __ Push(rbx); 428 __ Push(rbx);
429 if (use_new_target) {
430 __ Push(rdx);
431 }
421 __ Push(rbx); 432 __ Push(rbx);
422 433
423 // Set up pointer to last argument. 434 // Set up pointer to last argument.
424 __ leap(rbx, Operand(rbp, StandardFrameConstants::kCallerSPOffset)); 435 __ leap(rbx, Operand(rbp, StandardFrameConstants::kCallerSPOffset));
425 436
426 // Copy arguments and receiver to the expression stack. 437 // Copy arguments and receiver to the expression stack.
427 Label loop, entry; 438 Label loop, entry;
428 __ movp(rcx, rax); 439 __ movp(rcx, rax);
429 __ jmp(&entry); 440 __ jmp(&entry);
430 __ bind(&loop); 441 __ bind(&loop);
431 __ Push(Operand(rbx, rcx, times_pointer_size, 0)); 442 __ Push(Operand(rbx, rcx, times_pointer_size, 0));
432 __ bind(&entry); 443 __ bind(&entry);
433 __ decp(rcx); 444 __ decp(rcx);
434 __ j(greater_equal, &loop); 445 __ j(greater_equal, &loop);
435 446
447 // if (use_new_target) {
448 // __ incp(rax); // Pushed new.target
449 // }
450
436 // Call the function. 451 // Call the function.
437 if (is_api_function) { 452 if (is_api_function) {
438 __ movp(rsi, FieldOperand(rdi, JSFunction::kContextOffset)); 453 __ movp(rsi, FieldOperand(rdi, JSFunction::kContextOffset));
439 Handle<Code> code = 454 Handle<Code> code =
440 masm->isolate()->builtins()->HandleApiCallConstruct(); 455 masm->isolate()->builtins()->HandleApiCallConstruct();
441 __ Call(code, RelocInfo::CODE_TARGET); 456 __ Call(code, RelocInfo::CODE_TARGET);
442 } else { 457 } else {
443 ParameterCount actual(rax); 458 ParameterCount actual(rax);
444 __ InvokeFunction(rdi, actual, CALL_FUNCTION, NullCallWrapper()); 459 __ InvokeFunction(rdi, actual, CALL_FUNCTION, NullCallWrapper());
445 } 460 }
446 461
447 // Store offset of return address for deoptimizer. 462 // Store offset of return address for deoptimizer.
448 if (!is_api_function) { 463 if (!is_api_function && !use_new_target) {
449 masm->isolate()->heap()->SetConstructStubDeoptPCOffset(masm->pc_offset()); 464 masm->isolate()->heap()->SetConstructStubDeoptPCOffset(masm->pc_offset());
450 } 465 }
451 466
452 // Restore context from the frame. 467 // Restore context from the frame.
453 __ movp(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); 468 __ movp(rsi, Operand(rbp, StandardFrameConstants::kContextOffset));
454 469
455 // If the result is an object (in the ECMA sense), we should get rid 470 // If the result is an object (in the ECMA sense), we should get rid
456 // of the receiver and use the result; see ECMA-262 section 13.2.2-7 471 // of the receiver and use the result; see ECMA-262 section 13.2.2-7
457 // on page 74. 472 // on page 74.
458 Label use_receiver, exit; 473 Label use_receiver, exit;
459 // If the result is a smi, it is *not* an object in the ECMA sense. 474 // If the result is a smi, it is *not* an object in the ECMA sense.
460 __ JumpIfSmi(rax, &use_receiver); 475 __ JumpIfSmi(rax, &use_receiver);
461 476
462 // If the type of the result (stored in its map) is less than 477 // If the type of the result (stored in its map) is less than
463 // FIRST_SPEC_OBJECT_TYPE, it is not an object in the ECMA sense. 478 // FIRST_SPEC_OBJECT_TYPE, it is not an object in the ECMA sense.
464 STATIC_ASSERT(LAST_SPEC_OBJECT_TYPE == LAST_TYPE); 479 STATIC_ASSERT(LAST_SPEC_OBJECT_TYPE == LAST_TYPE);
465 __ CmpObjectType(rax, FIRST_SPEC_OBJECT_TYPE, rcx); 480 __ CmpObjectType(rax, FIRST_SPEC_OBJECT_TYPE, rcx);
466 __ j(above_equal, &exit); 481 __ j(above_equal, &exit);
467 482
468 // Throw away the result of the constructor invocation and use the 483 // Throw away the result of the constructor invocation and use the
469 // on-stack receiver as the result. 484 // on-stack receiver as the result.
470 __ bind(&use_receiver); 485 __ bind(&use_receiver);
471 __ movp(rax, Operand(rsp, 0)); 486 __ movp(rax, Operand(rsp, (use_new_target ? 1 : 0) * kPointerSize));
472 487
473 // Restore the arguments count and leave the construct frame. 488 // Restore the arguments count and leave the construct frame.
474 __ bind(&exit); 489 __ bind(&exit);
475 __ movp(rbx, Operand(rsp, kPointerSize)); // Get arguments count. 490 // Get arguments count.
491 int offset = (use_new_target ? 2 : 1) * kPointerSize;
492 __ movp(rbx, Operand(rsp, offset));
476 493
477 // Leave construct frame. 494 // Leave construct frame.
478 } 495 }
479 496
480 // Remove caller arguments from the stack and return. 497 // Remove caller arguments from the stack and return.
481 __ PopReturnAddressTo(rcx); 498 __ PopReturnAddressTo(rcx);
482 SmiIndex index = masm->SmiToIndex(rbx, rbx, kPointerSizeLog2); 499 SmiIndex index = masm->SmiToIndex(rbx, rbx, kPointerSizeLog2);
483 __ leap(rsp, Operand(rsp, index.reg, index.scale, 1 * kPointerSize)); 500 __ leap(rsp, Operand(rsp, index.reg, index.scale, 1 * kPointerSize));
484 __ PushReturnAddressFrom(rcx); 501 __ PushReturnAddressFrom(rcx);
485 Counters* counters = masm->isolate()->counters(); 502 Counters* counters = masm->isolate()->counters();
486 __ IncrementCounter(counters->constructed_objects(), 1); 503 __ IncrementCounter(counters->constructed_objects(), 1);
487 __ ret(0); 504 __ ret(0);
488 } 505 }
489 506
490 507
491 void Builtins::Generate_JSConstructStubGeneric(MacroAssembler* masm) { 508 void Builtins::Generate_JSConstructStubGeneric(MacroAssembler* masm) {
492 Generate_JSConstructStubHelper(masm, false, FLAG_pretenuring_call_new); 509 Generate_JSConstructStubHelper(masm, false, false, FLAG_pretenuring_call_new);
493 } 510 }
494 511
495 512
496 void Builtins::Generate_JSConstructStubApi(MacroAssembler* masm) { 513 void Builtins::Generate_JSConstructStubApi(MacroAssembler* masm) {
497 Generate_JSConstructStubHelper(masm, true, false); 514 Generate_JSConstructStubHelper(masm, true, false, false);
498 } 515 }
499 516
500 517
518 void Builtins::Generate_JSConstructStubNewTarget(MacroAssembler* masm) {
519 Generate_JSConstructStubHelper(masm, false, true, FLAG_pretenuring_call_new);
520 }
521
522
501 void Builtins::Generate_JSConstructStubForDerived(MacroAssembler* masm) { 523 void Builtins::Generate_JSConstructStubForDerived(MacroAssembler* masm) {
502 // ----------- S t a t e ------------- 524 // ----------- S t a t e -------------
503 // -- rax: number of arguments 525 // -- rax: number of arguments
504 // -- rdi: constructor function 526 // -- rdi: constructor function
505 // -- rbx: allocation site or undefined 527 // -- rbx: allocation site or undefined
506 // -- rdx: original constructor 528 // -- rdx: original constructor
507 // ----------------------------------- 529 // -----------------------------------
508 // TODO(dslomov): support pretenuring 530 // TODO(dslomov): support pretenuring
509 CHECK(!FLAG_pretenuring_call_new); 531 CHECK(!FLAG_pretenuring_call_new);
510 532
(...skipping 17 matching lines...) Expand all
528 // Copy arguments and receiver to the expression stack. 550 // Copy arguments and receiver to the expression stack.
529 Label loop, entry; 551 Label loop, entry;
530 __ movp(rcx, rax); 552 __ movp(rcx, rax);
531 __ jmp(&entry); 553 __ jmp(&entry);
532 __ bind(&loop); 554 __ bind(&loop);
533 __ Push(Operand(rbx, rcx, times_pointer_size, 0)); 555 __ Push(Operand(rbx, rcx, times_pointer_size, 0));
534 __ bind(&entry); 556 __ bind(&entry);
535 __ decp(rcx); 557 __ decp(rcx);
536 __ j(greater_equal, &loop); 558 __ j(greater_equal, &loop);
537 559
538 __ incp(rax); // Pushed new.target. 560 // __ incp(rax); // Pushed new.target.
539 561
540 // Handle step in. 562 // Handle step in.
541 Label skip_step_in; 563 Label skip_step_in;
542 ExternalReference debug_step_in_fp = 564 ExternalReference debug_step_in_fp =
543 ExternalReference::debug_step_in_fp_address(masm->isolate()); 565 ExternalReference::debug_step_in_fp_address(masm->isolate());
544 __ Move(kScratchRegister, debug_step_in_fp); 566 __ Move(kScratchRegister, debug_step_in_fp);
545 __ cmpp(Operand(kScratchRegister, 0), Immediate(0)); 567 __ cmpp(Operand(kScratchRegister, 0), Immediate(0));
546 __ j(equal, &skip_step_in); 568 __ j(equal, &skip_step_in);
547 569
548 __ Push(rax); 570 __ Push(rax);
549 __ Push(rdi); 571 __ Push(rdi);
550 __ Push(rdi); 572 __ Push(rdi);
551 __ CallRuntime(Runtime::kHandleStepInForDerivedConstructors, 1); 573 __ CallRuntime(Runtime::kHandleStepInForDerivedConstructors, 1);
552 __ Pop(rdi); 574 __ Pop(rdi);
553 __ Pop(rax); 575 __ Pop(rax);
554 576
555 __ bind(&skip_step_in); 577 __ bind(&skip_step_in);
556 578
557 // Call the function. 579 // Call the function.
558 ParameterCount actual(rax); 580 ParameterCount actual(rax);
559 __ InvokeFunction(rdi, actual, CALL_FUNCTION, NullCallWrapper()); 581 __ InvokeFunction(rdi, actual, CALL_FUNCTION, NullCallWrapper());
560 582
561 // Restore context from the frame. 583 // Restore context from the frame.
562 __ movp(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); 584 __ movp(rsi, Operand(rbp, StandardFrameConstants::kContextOffset));
563 585
564 __ movp(rbx, Operand(rsp, 0)); // Get arguments count. 586 // Get arguments count.
565 } // Leave construct frame. 587 __ movp(rbx, Operand(rsp, 0 * kPointerSize));
588
589 // Leave construct frame.
590 }
566 591
567 // Remove caller arguments from the stack and return. 592 // Remove caller arguments from the stack and return.
568 __ PopReturnAddressTo(rcx); 593 __ PopReturnAddressTo(rcx);
569 SmiIndex index = masm->SmiToIndex(rbx, rbx, kPointerSizeLog2); 594 SmiIndex index = masm->SmiToIndex(rbx, rbx, kPointerSizeLog2);
570 __ leap(rsp, Operand(rsp, index.reg, index.scale, 1 * kPointerSize)); 595 __ leap(rsp, Operand(rsp, index.reg, index.scale, 1 * kPointerSize));
571 __ PushReturnAddressFrom(rcx); 596 __ PushReturnAddressFrom(rcx);
572 __ ret(0); 597 __ ret(0);
573 } 598 }
574 599
575 600
(...skipping 749 matching lines...) Expand 10 before | Expand all | Expand 10 after
1325 masm, kArgumentsOffset, kIndexOffset, kLimitOffset); 1350 masm, kArgumentsOffset, kIndexOffset, kLimitOffset);
1326 1351
1327 // Use undefined feedback vector 1352 // Use undefined feedback vector
1328 __ LoadRoot(rbx, Heap::kUndefinedValueRootIndex); 1353 __ LoadRoot(rbx, Heap::kUndefinedValueRootIndex);
1329 __ movp(rdi, Operand(rbp, kFunctionOffset)); 1354 __ movp(rdi, Operand(rbp, kFunctionOffset));
1330 1355
1331 // Call the function. 1356 // Call the function.
1332 CallConstructStub stub(masm->isolate(), SUPER_CONSTRUCTOR_CALL); 1357 CallConstructStub stub(masm->isolate(), SUPER_CONSTRUCTOR_CALL);
1333 __ call(stub.GetCode(), RelocInfo::CONSTRUCT_CALL); 1358 __ call(stub.GetCode(), RelocInfo::CONSTRUCT_CALL);
1334 1359
1360 // TODO(arv): Double check this drop.
1335 __ Drop(1); 1361 __ Drop(1);
1336 1362
1337 // Leave internal frame. 1363 // Leave internal frame.
1338 } 1364 }
1339 // remove this, target, arguments and newTarget 1365 // remove this, target, arguments and newTarget
1340 __ ret(kStackSize * kPointerSize); 1366 __ ret(kStackSize * kPointerSize);
1341 } 1367 }
1342 1368
1343 1369
1344 void Builtins::Generate_FunctionApply(MacroAssembler* masm) { 1370 void Builtins::Generate_FunctionApply(MacroAssembler* masm) {
(...skipping 406 matching lines...) Expand 10 before | Expand all | Expand 10 after
1751 __ bind(&ok); 1777 __ bind(&ok);
1752 __ ret(0); 1778 __ ret(0);
1753 } 1779 }
1754 1780
1755 1781
1756 #undef __ 1782 #undef __
1757 1783
1758 } } // namespace v8::internal 1784 } } // namespace v8::internal
1759 1785
1760 #endif // V8_TARGET_ARCH_X64 1786 #endif // V8_TARGET_ARCH_X64
OLDNEW
« no previous file with comments | « src/scopes.cc ('k') | src/x64/full-codegen-x64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698