| 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/arm64/frames-arm64.h" | 7 #include "src/arm64/frames-arm64.h" |
| 8 #include "src/codegen.h" | 8 #include "src/codegen.h" |
| 9 #include "src/debug/debug.h" | 9 #include "src/debug/debug.h" |
| 10 #include "src/deoptimizer.h" | 10 #include "src/deoptimizer.h" |
| (...skipping 297 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 308 | 308 |
| 309 CallRuntimePassFunction(masm, Runtime::kTryInstallOptimizedCode); | 309 CallRuntimePassFunction(masm, Runtime::kTryInstallOptimizedCode); |
| 310 GenerateTailCallToReturnedCode(masm); | 310 GenerateTailCallToReturnedCode(masm); |
| 311 | 311 |
| 312 __ Bind(&ok); | 312 __ Bind(&ok); |
| 313 GenerateTailCallToSharedCode(masm); | 313 GenerateTailCallToSharedCode(masm); |
| 314 } | 314 } |
| 315 | 315 |
| 316 | 316 |
| 317 static void Generate_JSConstructStubHelper(MacroAssembler* masm, | 317 static void Generate_JSConstructStubHelper(MacroAssembler* masm, |
| 318 bool is_api_function, | 318 bool is_api_function) { |
| 319 bool create_memento) { | |
| 320 // ----------- S t a t e ------------- | 319 // ----------- S t a t e ------------- |
| 321 // -- x0 : number of arguments | 320 // -- x0 : number of arguments |
| 322 // -- x1 : constructor function | 321 // -- x1 : constructor function |
| 323 // -- x2 : allocation site or undefined | 322 // -- x2 : allocation site or undefined |
| 324 // -- x3 : original constructor | 323 // -- x3 : original constructor |
| 325 // -- lr : return address | 324 // -- lr : return address |
| 326 // -- sp[...]: constructor arguments | 325 // -- sp[...]: constructor arguments |
| 327 // ----------------------------------- | 326 // ----------------------------------- |
| 328 | 327 |
| 329 ASM_LOCATION("Builtins::Generate_JSConstructStubHelper"); | 328 ASM_LOCATION("Builtins::Generate_JSConstructStubHelper"); |
| 330 // Should never create mementos for api functions. | |
| 331 DCHECK(!is_api_function || !create_memento); | |
| 332 | 329 |
| 333 Isolate* isolate = masm->isolate(); | 330 Isolate* isolate = masm->isolate(); |
| 334 | 331 |
| 335 // Enter a construct frame. | 332 // Enter a construct frame. |
| 336 { | 333 { |
| 337 FrameScope scope(masm, StackFrame::CONSTRUCT); | 334 FrameScope scope(masm, StackFrame::CONSTRUCT); |
| 338 | 335 |
| 339 // Preserve the four incoming parameters on the stack. | 336 // Preserve the four incoming parameters on the stack. |
| 340 Register argc = x0; | 337 Register argc = x0; |
| 341 Register constructor = x1; | 338 Register constructor = x1; |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 402 __ Pop(init_map, constructor); | 399 __ Pop(init_map, constructor); |
| 403 __ Mov(constructon_count, Operand(Map::kSlackTrackingCounterEnd - 1)); | 400 __ Mov(constructon_count, Operand(Map::kSlackTrackingCounterEnd - 1)); |
| 404 __ Bind(&allocate); | 401 __ Bind(&allocate); |
| 405 } | 402 } |
| 406 | 403 |
| 407 // Now allocate the JSObject on the heap. | 404 // Now allocate the JSObject on the heap. |
| 408 Label rt_call_reload_new_target; | 405 Label rt_call_reload_new_target; |
| 409 Register obj_size = x3; | 406 Register obj_size = x3; |
| 410 Register new_obj = x4; | 407 Register new_obj = x4; |
| 411 __ Ldrb(obj_size, FieldMemOperand(init_map, Map::kInstanceSizeOffset)); | 408 __ Ldrb(obj_size, FieldMemOperand(init_map, Map::kInstanceSizeOffset)); |
| 412 if (create_memento) { | 409 __ Allocate(obj_size, new_obj, x10, x11, &rt_call_reload_new_target, |
| 413 __ Add(x7, obj_size, | 410 SIZE_IN_WORDS); |
| 414 Operand(AllocationMemento::kSize / kPointerSize)); | |
| 415 __ Allocate(x7, new_obj, x10, x11, &rt_call_reload_new_target, | |
| 416 SIZE_IN_WORDS); | |
| 417 } else { | |
| 418 __ Allocate(obj_size, new_obj, x10, x11, &rt_call_reload_new_target, | |
| 419 SIZE_IN_WORDS); | |
| 420 } | |
| 421 | 411 |
| 422 // Allocated the JSObject, now initialize the fields. Map is set to | 412 // Allocated the JSObject, now initialize the fields. Map is set to |
| 423 // initial map and properties and elements are set to empty fixed array. | 413 // initial map and properties and elements are set to empty fixed array. |
| 424 // NB. the object pointer is not tagged, so MemOperand is used. | 414 // NB. the object pointer is not tagged, so MemOperand is used. |
| 425 Register empty = x5; | 415 Register empty = x5; |
| 426 __ LoadRoot(empty, Heap::kEmptyFixedArrayRootIndex); | 416 __ LoadRoot(empty, Heap::kEmptyFixedArrayRootIndex); |
| 427 __ Str(init_map, MemOperand(new_obj, JSObject::kMapOffset)); | 417 __ Str(init_map, MemOperand(new_obj, JSObject::kMapOffset)); |
| 428 STATIC_ASSERT(JSObject::kElementsOffset == | 418 STATIC_ASSERT(JSObject::kElementsOffset == |
| 429 (JSObject::kPropertiesOffset + kPointerSize)); | 419 (JSObject::kPropertiesOffset + kPointerSize)); |
| 430 __ Stp(empty, empty, MemOperand(new_obj, JSObject::kPropertiesOffset)); | 420 __ Stp(empty, empty, MemOperand(new_obj, JSObject::kPropertiesOffset)); |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 480 __ Cmp(first_prop, obj_end); | 470 __ Cmp(first_prop, obj_end); |
| 481 __ Assert(le, kUnexpectedNumberOfPreAllocatedPropertyFields); | 471 __ Assert(le, kUnexpectedNumberOfPreAllocatedPropertyFields); |
| 482 } | 472 } |
| 483 | 473 |
| 484 // Fill the remaining fields with one pointer filler map. | 474 // Fill the remaining fields with one pointer filler map. |
| 485 __ LoadRoot(filler, Heap::kOnePointerFillerMapRootIndex); | 475 __ LoadRoot(filler, Heap::kOnePointerFillerMapRootIndex); |
| 486 __ Sub(prop_fields, prop_fields, prealloc_fields); | 476 __ Sub(prop_fields, prop_fields, prealloc_fields); |
| 487 | 477 |
| 488 __ bind(&no_inobject_slack_tracking); | 478 __ bind(&no_inobject_slack_tracking); |
| 489 } | 479 } |
| 490 if (create_memento) { | 480 |
| 491 // Fill the pre-allocated fields with undef. | 481 // Fill all of the property fields with undef. |
| 492 __ FillFields(first_prop, prop_fields, filler); | 482 __ FillFields(first_prop, prop_fields, filler); |
| 493 __ Add(first_prop, new_obj, Operand(obj_size, LSL, kPointerSizeLog2)); | 483 first_prop = NoReg; |
| 494 __ LoadRoot(x14, Heap::kAllocationMementoMapRootIndex); | 484 prop_fields = NoReg; |
| 495 DCHECK_EQ(0 * kPointerSize, AllocationMemento::kMapOffset); | |
| 496 __ Str(x14, MemOperand(first_prop, kPointerSize, PostIndex)); | |
| 497 // Load the AllocationSite | |
| 498 __ Peek(x14, 3 * kXRegSize); | |
| 499 __ AssertUndefinedOrAllocationSite(x14, x10); | |
| 500 DCHECK_EQ(1 * kPointerSize, AllocationMemento::kAllocationSiteOffset); | |
| 501 __ Str(x14, MemOperand(first_prop, kPointerSize, PostIndex)); | |
| 502 first_prop = NoReg; | |
| 503 } else { | |
| 504 // Fill all of the property fields with undef. | |
| 505 __ FillFields(first_prop, prop_fields, filler); | |
| 506 first_prop = NoReg; | |
| 507 prop_fields = NoReg; | |
| 508 } | |
| 509 | 485 |
| 510 // Add the object tag to make the JSObject real, so that we can continue | 486 // Add the object tag to make the JSObject real, so that we can continue |
| 511 // and jump into the continuation code at any time from now on. | 487 // and jump into the continuation code at any time from now on. |
| 512 __ Add(new_obj, new_obj, kHeapObjectTag); | 488 __ Add(new_obj, new_obj, kHeapObjectTag); |
| 513 | 489 |
| 514 // Continue with JSObject being successfully allocated. | 490 // Continue with JSObject being successfully allocated. |
| 515 __ B(&allocated); | 491 __ B(&allocated); |
| 516 | 492 |
| 517 // Reload the original constructor and fall-through. | 493 // Reload the original constructor and fall-through. |
| 518 __ Bind(&rt_call_reload_new_target); | 494 __ Bind(&rt_call_reload_new_target); |
| 519 __ Peek(x3, 0 * kXRegSize); | 495 __ Peek(x3, 0 * kXRegSize); |
| 520 } | 496 } |
| 521 | 497 |
| 522 // Allocate the new receiver object using the runtime call. | 498 // Allocate the new receiver object using the runtime call. |
| 523 // x1: constructor function | 499 // x1: constructor function |
| 524 // x3: original constructor | 500 // x3: original constructor |
| 525 __ Bind(&rt_call); | 501 __ Bind(&rt_call); |
| 526 Label count_incremented; | 502 __ Push(constructor, original_constructor); // arguments 1-2 |
| 527 if (create_memento) { | 503 __ CallRuntime(Runtime::kNewObject, 2); |
| 528 // Get the cell or allocation site. | 504 __ Mov(x4, x0); |
| 529 __ Peek(x4, 3 * kXRegSize); | |
| 530 __ Push(x4, constructor, original_constructor); // arguments 1-3 | |
| 531 __ CallRuntime(Runtime::kNewObjectWithAllocationSite, 3); | |
| 532 __ Mov(x4, x0); | |
| 533 // If we ended up using the runtime, and we want a memento, then the | |
| 534 // runtime call made it for us, and we shouldn't do create count | |
| 535 // increment. | |
| 536 __ B(&count_incremented); | |
| 537 } else { | |
| 538 __ Push(constructor, original_constructor); // arguments 1-2 | |
| 539 __ CallRuntime(Runtime::kNewObject, 2); | |
| 540 __ Mov(x4, x0); | |
| 541 } | |
| 542 | 505 |
| 543 // Receiver for constructor call allocated. | 506 // Receiver for constructor call allocated. |
| 544 // x4: JSObject | 507 // x4: JSObject |
| 545 __ Bind(&allocated); | 508 __ Bind(&allocated); |
| 546 | 509 |
| 547 if (create_memento) { | |
| 548 __ Peek(x10, 3 * kXRegSize); | |
| 549 __ JumpIfRoot(x10, Heap::kUndefinedValueRootIndex, &count_incremented); | |
| 550 // r2 is an AllocationSite. We are creating a memento from it, so we | |
| 551 // need to increment the memento create count. | |
| 552 __ Ldr(x5, FieldMemOperand(x10, | |
| 553 AllocationSite::kPretenureCreateCountOffset)); | |
| 554 __ Add(x5, x5, Operand(Smi::FromInt(1))); | |
| 555 __ Str(x5, FieldMemOperand(x10, | |
| 556 AllocationSite::kPretenureCreateCountOffset)); | |
| 557 __ bind(&count_incremented); | |
| 558 } | |
| 559 | |
| 560 // Restore the parameters. | 510 // Restore the parameters. |
| 561 __ Pop(original_constructor); | 511 __ Pop(original_constructor); |
| 562 __ Pop(constructor); | 512 __ Pop(constructor); |
| 563 | 513 |
| 564 // Reload the number of arguments from the stack. | 514 // Reload the number of arguments from the stack. |
| 565 // Set it up in x0 for the function call below. | 515 // Set it up in x0 for the function call below. |
| 566 // jssp[0]: number of arguments (smi-tagged) | 516 // jssp[0]: number of arguments (smi-tagged) |
| 567 __ Peek(argc, 0); // Load number of arguments. | 517 __ Peek(argc, 0); // Load number of arguments. |
| 568 __ SmiUntag(argc); | 518 __ SmiUntag(argc); |
| 569 | 519 |
| (...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 655 } | 605 } |
| 656 | 606 |
| 657 __ DropBySMI(x1); | 607 __ DropBySMI(x1); |
| 658 __ Drop(1); | 608 __ Drop(1); |
| 659 __ IncrementCounter(isolate->counters()->constructed_objects(), 1, x1, x2); | 609 __ IncrementCounter(isolate->counters()->constructed_objects(), 1, x1, x2); |
| 660 __ Ret(); | 610 __ Ret(); |
| 661 } | 611 } |
| 662 | 612 |
| 663 | 613 |
| 664 void Builtins::Generate_JSConstructStubGeneric(MacroAssembler* masm) { | 614 void Builtins::Generate_JSConstructStubGeneric(MacroAssembler* masm) { |
| 665 Generate_JSConstructStubHelper(masm, false, FLAG_pretenuring_call_new); | 615 Generate_JSConstructStubHelper(masm, false); |
| 666 } | 616 } |
| 667 | 617 |
| 668 | 618 |
| 669 void Builtins::Generate_JSConstructStubApi(MacroAssembler* masm) { | 619 void Builtins::Generate_JSConstructStubApi(MacroAssembler* masm) { |
| 670 Generate_JSConstructStubHelper(masm, true, false); | 620 Generate_JSConstructStubHelper(masm, true); |
| 671 } | 621 } |
| 672 | 622 |
| 673 | 623 |
| 674 void Builtins::Generate_JSConstructStubForDerived(MacroAssembler* masm) { | 624 void Builtins::Generate_JSConstructStubForDerived(MacroAssembler* masm) { |
| 675 // ----------- S t a t e ------------- | 625 // ----------- S t a t e ------------- |
| 676 // -- x0 : number of arguments | 626 // -- x0 : number of arguments |
| 677 // -- x1 : constructor function | 627 // -- x1 : constructor function |
| 678 // -- x2 : allocation site or undefined | 628 // -- x2 : allocation site or undefined |
| 679 // -- x3 : original constructor | 629 // -- x3 : original constructor |
| 680 // -- lr : return address | 630 // -- lr : return address |
| (...skipping 1248 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1929 } | 1879 } |
| 1930 } | 1880 } |
| 1931 | 1881 |
| 1932 | 1882 |
| 1933 #undef __ | 1883 #undef __ |
| 1934 | 1884 |
| 1935 } // namespace internal | 1885 } // namespace internal |
| 1936 } // namespace v8 | 1886 } // namespace v8 |
| 1937 | 1887 |
| 1938 #endif // V8_TARGET_ARCH_ARM | 1888 #endif // V8_TARGET_ARCH_ARM |
| OLD | NEW |