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

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

Issue 1213623020: Remove separate construct stub for new.target users. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Ported to all architectures. Created 5 years, 5 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/mips64/builtins-mips64.cc ('k') | no next file » | 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 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
97 __ bind(&ok); 97 __ bind(&ok);
98 GenerateTailCallToSharedCode(masm); 98 GenerateTailCallToSharedCode(masm);
99 } 99 }
100 100
101 101
102 static void Generate_Runtime_NewObject(MacroAssembler* masm, 102 static void Generate_Runtime_NewObject(MacroAssembler* masm,
103 bool create_memento, 103 bool create_memento,
104 Register original_constructor, 104 Register original_constructor,
105 Label* count_incremented, 105 Label* count_incremented,
106 Label* allocated) { 106 Label* allocated) {
107 int offset = 0; 107 int offset = kPointerSize;
108 if (create_memento) { 108 if (create_memento) {
109 // Get the cell or allocation site. 109 // Get the cell or allocation site.
110 __ movp(rdi, Operand(rsp, kPointerSize * 2)); 110 __ movp(rdi, Operand(rsp, kPointerSize * 3));
111 __ Push(rdi); 111 __ Push(rdi);
112 offset = kPointerSize; 112 offset += kPointerSize;
113 } 113 }
114 114
115 // Must restore rsi (context) and rdi (constructor) before calling runtime. 115 // Must restore rsi (context) and rdi (constructor) before calling runtime.
116 __ movp(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); 116 __ movp(rsi, Operand(rbp, StandardFrameConstants::kContextOffset));
117 __ movp(rdi, Operand(rsp, offset)); 117 __ movp(rdi, Operand(rsp, offset));
118 __ Push(rdi); 118 __ Push(rdi);
119 __ Push(original_constructor); 119 __ Push(original_constructor);
120 if (create_memento) { 120 if (create_memento) {
121 __ CallRuntime(Runtime::kNewObjectWithAllocationSite, 3); 121 __ CallRuntime(Runtime::kNewObjectWithAllocationSite, 3);
122 } else { 122 } else {
123 __ CallRuntime(Runtime::kNewObject, 2); 123 __ CallRuntime(Runtime::kNewObject, 2);
124 } 124 }
125 __ movp(rbx, rax); // store result in rbx 125 __ movp(rbx, rax); // store result in rbx
126 126
127 // Runtime_NewObjectWithAllocationSite increments allocation count. 127 // Runtime_NewObjectWithAllocationSite increments allocation count.
128 // Skip the increment. 128 // Skip the increment.
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,
140 bool create_memento) { 139 bool create_memento) {
141 // ----------- S t a t e ------------- 140 // ----------- S t a t e -------------
142 // -- rax: number of arguments 141 // -- rax: number of arguments
143 // -- rdi: constructor function 142 // -- rdi: constructor function
144 // -- rbx: allocation site or undefined 143 // -- rbx: allocation site or undefined
145 // -- rdx: original constructor 144 // -- rdx: original constructor
146 // ----------------------------------- 145 // -----------------------------------
147 146
148 // Should never create mementos for api functions. 147 // Should never create mementos for api functions.
149 DCHECK(!is_api_function || !create_memento); 148 DCHECK(!is_api_function || !create_memento);
150 149
151 // Enter a construct frame. 150 // Enter a construct frame.
152 { 151 {
153 FrameScope scope(masm, StackFrame::CONSTRUCT); 152 FrameScope scope(masm, StackFrame::CONSTRUCT);
154 153
155 if (create_memento) { 154 if (create_memento) {
156 __ AssertUndefinedOrAllocationSite(rbx); 155 __ AssertUndefinedOrAllocationSite(rbx);
157 __ Push(rbx); 156 __ Push(rbx);
158 } 157 }
159 158
160 // Preserve the incoming parameters on the stack. 159 // Preserve the incoming parameters on the stack.
161 __ Integer32ToSmi(rax, rax); 160 __ Integer32ToSmi(rax, rax);
162 __ Push(rax); 161 __ Push(rax);
163 __ Push(rdi); 162 __ Push(rdi);
164 if (use_new_target) { 163 __ Push(rdx);
165 __ Push(rdx);
166 }
167 164
168 Label rt_call, normal_new, allocated, count_incremented; 165 Label rt_call, normal_new, allocated, count_incremented;
169 __ cmpp(rdx, rdi); 166 __ cmpp(rdx, rdi);
170 __ j(equal, &normal_new); 167 __ j(equal, &normal_new);
171 168
172 Generate_Runtime_NewObject(masm, create_memento, rdx, &count_incremented, 169 Generate_Runtime_NewObject(masm, create_memento, rdx, &count_incremented,
173 &allocated); 170 &allocated);
174 171
175 __ bind(&normal_new); 172 __ bind(&normal_new);
176 // Try to allocate the object without transitioning into C code. If any of 173 // Try to allocate the object without transitioning into C code. If any of
(...skipping 206 matching lines...) Expand 10 before | Expand all | Expand 10 after
383 // rdi: function (constructor) 380 // rdi: function (constructor)
384 __ bind(&rt_call); 381 __ bind(&rt_call);
385 Generate_Runtime_NewObject(masm, create_memento, rdi, &count_incremented, 382 Generate_Runtime_NewObject(masm, create_memento, rdi, &count_incremented,
386 &allocated); 383 &allocated);
387 384
388 // New object allocated. 385 // New object allocated.
389 // rbx: newly allocated object 386 // rbx: newly allocated object
390 __ bind(&allocated); 387 __ bind(&allocated);
391 388
392 if (create_memento) { 389 if (create_memento) {
393 int offset = (use_new_target ? 3 : 2) * kPointerSize; 390 __ movp(rcx, Operand(rsp, 3 * kPointerSize));
394 __ movp(rcx, Operand(rsp, offset));
395 __ Cmp(rcx, masm->isolate()->factory()->undefined_value()); 391 __ Cmp(rcx, masm->isolate()->factory()->undefined_value());
396 __ j(equal, &count_incremented); 392 __ j(equal, &count_incremented);
397 // rcx is an AllocationSite. We are creating a memento from it, so we 393 // rcx is an AllocationSite. We are creating a memento from it, so we
398 // need to increment the memento create count. 394 // need to increment the memento create count.
399 __ SmiAddConstant( 395 __ SmiAddConstant(
400 FieldOperand(rcx, AllocationSite::kPretenureCreateCountOffset), 396 FieldOperand(rcx, AllocationSite::kPretenureCreateCountOffset),
401 Smi::FromInt(1)); 397 Smi::FromInt(1));
402 __ bind(&count_incremented); 398 __ bind(&count_incremented);
403 } 399 }
404 400
405 // Restore the parameters. 401 // Restore the parameters.
406 if (use_new_target) { 402 __ Pop(rdx);
407 __ Pop(rdx);
408 }
409 __ Pop(rdi); 403 __ Pop(rdi);
410 404
411 // Retrieve smi-tagged arguments count from the stack. 405 // Retrieve smi-tagged arguments count from the stack.
412 __ movp(rax, Operand(rsp, 0)); 406 __ movp(rax, Operand(rsp, 0));
413 __ SmiToInteger32(rax, rax); 407 __ SmiToInteger32(rax, rax);
414 408
415 // Push new.target onto the construct frame. This is stored just below the 409 // Push new.target onto the construct frame. This is stored just below the
416 // receiver on the stack. 410 // receiver on the stack.
417 if (use_new_target) { 411 __ Push(rdx);
418 __ Push(rdx);
419 }
420 412
421 // Push the allocated receiver to the stack. We need two copies 413 // Push the allocated receiver to the stack. We need two copies
422 // because we may have to return the original one and the calling 414 // because we may have to return the original one and the calling
423 // conventions dictate that the called function pops the receiver. 415 // conventions dictate that the called function pops the receiver.
424 __ Push(rbx); 416 __ Push(rbx);
425 __ Push(rbx); 417 __ Push(rbx);
426 418
427 // Set up pointer to last argument. 419 // Set up pointer to last argument.
428 __ leap(rbx, Operand(rbp, StandardFrameConstants::kCallerSPOffset)); 420 __ leap(rbx, Operand(rbp, StandardFrameConstants::kCallerSPOffset));
429 421
(...skipping 12 matching lines...) Expand all
442 __ movp(rsi, FieldOperand(rdi, JSFunction::kContextOffset)); 434 __ movp(rsi, FieldOperand(rdi, JSFunction::kContextOffset));
443 Handle<Code> code = 435 Handle<Code> code =
444 masm->isolate()->builtins()->HandleApiCallConstruct(); 436 masm->isolate()->builtins()->HandleApiCallConstruct();
445 __ Call(code, RelocInfo::CODE_TARGET); 437 __ Call(code, RelocInfo::CODE_TARGET);
446 } else { 438 } else {
447 ParameterCount actual(rax); 439 ParameterCount actual(rax);
448 __ InvokeFunction(rdi, actual, CALL_FUNCTION, NullCallWrapper()); 440 __ InvokeFunction(rdi, actual, CALL_FUNCTION, NullCallWrapper());
449 } 441 }
450 442
451 // Store offset of return address for deoptimizer. 443 // Store offset of return address for deoptimizer.
452 // TODO(arv): Remove the "!use_new_target" before supporting optimization 444 if (!is_api_function) {
453 // of functions that reference new.target
454 if (!is_api_function && !use_new_target) {
455 masm->isolate()->heap()->SetConstructStubDeoptPCOffset(masm->pc_offset()); 445 masm->isolate()->heap()->SetConstructStubDeoptPCOffset(masm->pc_offset());
456 } 446 }
457 447
458 // Restore context from the frame. 448 // Restore context from the frame.
459 __ movp(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); 449 __ movp(rsi, Operand(rbp, StandardFrameConstants::kContextOffset));
460 450
461 // If the result is an object (in the ECMA sense), we should get rid 451 // If the result is an object (in the ECMA sense), we should get rid
462 // of the receiver and use the result; see ECMA-262 section 13.2.2-7 452 // of the receiver and use the result; see ECMA-262 section 13.2.2-7
463 // on page 74. 453 // on page 74.
464 Label use_receiver, exit; 454 Label use_receiver, exit;
465 // If the result is a smi, it is *not* an object in the ECMA sense. 455 // If the result is a smi, it is *not* an object in the ECMA sense.
466 __ JumpIfSmi(rax, &use_receiver); 456 __ JumpIfSmi(rax, &use_receiver);
467 457
468 // If the type of the result (stored in its map) is less than 458 // If the type of the result (stored in its map) is less than
469 // FIRST_SPEC_OBJECT_TYPE, it is not an object in the ECMA sense. 459 // FIRST_SPEC_OBJECT_TYPE, it is not an object in the ECMA sense.
470 STATIC_ASSERT(LAST_SPEC_OBJECT_TYPE == LAST_TYPE); 460 STATIC_ASSERT(LAST_SPEC_OBJECT_TYPE == LAST_TYPE);
471 __ CmpObjectType(rax, FIRST_SPEC_OBJECT_TYPE, rcx); 461 __ CmpObjectType(rax, FIRST_SPEC_OBJECT_TYPE, rcx);
472 __ j(above_equal, &exit); 462 __ j(above_equal, &exit);
473 463
474 // Throw away the result of the constructor invocation and use the 464 // Throw away the result of the constructor invocation and use the
475 // on-stack receiver as the result. 465 // on-stack receiver as the result.
476 __ bind(&use_receiver); 466 __ bind(&use_receiver);
477 __ movp(rax, Operand(rsp, 0)); 467 __ movp(rax, Operand(rsp, 0));
478 468
479 // Restore the arguments count and leave the construct frame. The arguments 469 // Restore the arguments count and leave the construct frame. The arguments
480 // count is stored below the reciever and the new.target. 470 // count is stored below the reciever and the new.target.
481 __ bind(&exit); 471 __ bind(&exit);
482 int offset = (use_new_target ? 2 : 1) * kPointerSize; 472 __ movp(rbx, Operand(rsp, 2 * kPointerSize));
483 __ movp(rbx, Operand(rsp, offset));
484 473
485 // Leave construct frame. 474 // Leave construct frame.
486 } 475 }
487 476
488 // Remove caller arguments from the stack and return. 477 // Remove caller arguments from the stack and return.
489 __ PopReturnAddressTo(rcx); 478 __ PopReturnAddressTo(rcx);
490 SmiIndex index = masm->SmiToIndex(rbx, rbx, kPointerSizeLog2); 479 SmiIndex index = masm->SmiToIndex(rbx, rbx, kPointerSizeLog2);
491 __ leap(rsp, Operand(rsp, index.reg, index.scale, 1 * kPointerSize)); 480 __ leap(rsp, Operand(rsp, index.reg, index.scale, 1 * kPointerSize));
492 __ PushReturnAddressFrom(rcx); 481 __ PushReturnAddressFrom(rcx);
493 Counters* counters = masm->isolate()->counters(); 482 Counters* counters = masm->isolate()->counters();
494 __ IncrementCounter(counters->constructed_objects(), 1); 483 __ IncrementCounter(counters->constructed_objects(), 1);
495 __ ret(0); 484 __ ret(0);
496 } 485 }
497 486
498 487
499 void Builtins::Generate_JSConstructStubGeneric(MacroAssembler* masm) { 488 void Builtins::Generate_JSConstructStubGeneric(MacroAssembler* masm) {
500 Generate_JSConstructStubHelper(masm, false, false, FLAG_pretenuring_call_new); 489 Generate_JSConstructStubHelper(masm, false, FLAG_pretenuring_call_new);
501 } 490 }
502 491
503 492
504 void Builtins::Generate_JSConstructStubApi(MacroAssembler* masm) { 493 void Builtins::Generate_JSConstructStubApi(MacroAssembler* masm) {
505 Generate_JSConstructStubHelper(masm, true, false, false); 494 Generate_JSConstructStubHelper(masm, true, false);
506 } 495 }
507 496
508 497
509 void Builtins::Generate_JSConstructStubNewTarget(MacroAssembler* masm) {
510 Generate_JSConstructStubHelper(masm, false, true, FLAG_pretenuring_call_new);
511 }
512
513
514 void Builtins::Generate_JSConstructStubForDerived(MacroAssembler* masm) { 498 void Builtins::Generate_JSConstructStubForDerived(MacroAssembler* masm) {
515 // ----------- S t a t e ------------- 499 // ----------- S t a t e -------------
516 // -- rax: number of arguments 500 // -- rax: number of arguments
517 // -- rdi: constructor function 501 // -- rdi: constructor function
518 // -- rbx: allocation site or undefined 502 // -- rbx: allocation site or undefined
519 // -- rdx: original constructor 503 // -- rdx: original constructor
520 // ----------------------------------- 504 // -----------------------------------
521 // TODO(dslomov): support pretenuring 505 // TODO(dslomov): support pretenuring
522 CHECK(!FLAG_pretenuring_call_new); 506 CHECK(!FLAG_pretenuring_call_new);
523 507
(...skipping 1281 matching lines...) Expand 10 before | Expand all | Expand 10 after
1805 __ ret(0); 1789 __ ret(0);
1806 } 1790 }
1807 1791
1808 1792
1809 #undef __ 1793 #undef __
1810 1794
1811 } // namespace internal 1795 } // namespace internal
1812 } // namespace v8 1796 } // namespace v8
1813 1797
1814 #endif // V8_TARGET_ARCH_X64 1798 #endif // V8_TARGET_ARCH_X64
OLDNEW
« no previous file with comments | « src/mips64/builtins-mips64.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698