| 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 302 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 313 __ B(ne, &new_object); | 313 __ B(ne, &new_object); |
| 314 | 314 |
| 315 // 5. Allocate a JSValue wrapper for the number. | 315 // 5. Allocate a JSValue wrapper for the number. |
| 316 __ AllocateJSValue(x0, x1, x2, x4, x5, &new_object); | 316 __ AllocateJSValue(x0, x1, x2, x4, x5, &new_object); |
| 317 __ Ret(); | 317 __ Ret(); |
| 318 | 318 |
| 319 // 6. Fallback to the runtime to create new object. | 319 // 6. Fallback to the runtime to create new object. |
| 320 __ bind(&new_object); | 320 __ bind(&new_object); |
| 321 { | 321 { |
| 322 FrameScope scope(masm, StackFrame::INTERNAL); | 322 FrameScope scope(masm, StackFrame::INTERNAL); |
| 323 __ Push(x2, x1, x3); // first argument, constructor, new target | 323 __ Push(x2); // first argument |
| 324 __ CallRuntime(Runtime::kNewObject); | 324 FastNewObjectStub stub(masm->isolate()); |
| 325 __ CallStub(&stub); |
| 325 __ Pop(x2); | 326 __ Pop(x2); |
| 326 } | 327 } |
| 327 __ Str(x2, FieldMemOperand(x0, JSValue::kValueOffset)); | 328 __ Str(x2, FieldMemOperand(x0, JSValue::kValueOffset)); |
| 328 __ Ret(); | 329 __ Ret(); |
| 329 } | 330 } |
| 330 | 331 |
| 331 | 332 |
| 332 // static | 333 // static |
| 333 void Builtins::Generate_StringConstructor(MacroAssembler* masm) { | 334 void Builtins::Generate_StringConstructor(MacroAssembler* masm) { |
| 334 // ----------- S t a t e ------------- | 335 // ----------- S t a t e ------------- |
| (...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 440 __ B(ne, &new_object); | 441 __ B(ne, &new_object); |
| 441 | 442 |
| 442 // 5. Allocate a JSValue wrapper for the string. | 443 // 5. Allocate a JSValue wrapper for the string. |
| 443 __ AllocateJSValue(x0, x1, x2, x4, x5, &new_object); | 444 __ AllocateJSValue(x0, x1, x2, x4, x5, &new_object); |
| 444 __ Ret(); | 445 __ Ret(); |
| 445 | 446 |
| 446 // 6. Fallback to the runtime to create new object. | 447 // 6. Fallback to the runtime to create new object. |
| 447 __ bind(&new_object); | 448 __ bind(&new_object); |
| 448 { | 449 { |
| 449 FrameScope scope(masm, StackFrame::INTERNAL); | 450 FrameScope scope(masm, StackFrame::INTERNAL); |
| 450 __ Push(x2, x1, x3); // first argument, constructor, new target | 451 __ Push(x2); // first argument |
| 451 __ CallRuntime(Runtime::kNewObject); | 452 FastNewObjectStub stub(masm->isolate()); |
| 453 __ CallStub(&stub); |
| 452 __ Pop(x2); | 454 __ Pop(x2); |
| 453 } | 455 } |
| 454 __ Str(x2, FieldMemOperand(x0, JSValue::kValueOffset)); | 456 __ Str(x2, FieldMemOperand(x0, JSValue::kValueOffset)); |
| 455 __ Ret(); | 457 __ Ret(); |
| 456 } | 458 } |
| 457 | 459 |
| 458 static void GenerateTailCallToSharedCode(MacroAssembler* masm) { | 460 static void GenerateTailCallToSharedCode(MacroAssembler* masm) { |
| 459 __ Ldr(x2, FieldMemOperand(x1, JSFunction::kSharedFunctionInfoOffset)); | 461 __ Ldr(x2, FieldMemOperand(x1, JSFunction::kSharedFunctionInfoOffset)); |
| 460 __ Ldr(x2, FieldMemOperand(x2, SharedFunctionInfo::kCodeOffset)); | 462 __ Ldr(x2, FieldMemOperand(x2, SharedFunctionInfo::kCodeOffset)); |
| 461 __ Add(x2, x2, Code::kHeaderSize - kHeapObjectTag); | 463 __ Add(x2, x2, Code::kHeaderSize - kHeapObjectTag); |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 532 Register constructor = x1; | 534 Register constructor = x1; |
| 533 Register allocation_site = x2; | 535 Register allocation_site = x2; |
| 534 Register new_target = x3; | 536 Register new_target = x3; |
| 535 | 537 |
| 536 // Preserve the incoming parameters on the stack. | 538 // Preserve the incoming parameters on the stack. |
| 537 __ AssertUndefinedOrAllocationSite(allocation_site, x10); | 539 __ AssertUndefinedOrAllocationSite(allocation_site, x10); |
| 538 __ SmiTag(argc); | 540 __ SmiTag(argc); |
| 539 __ Push(allocation_site, argc); | 541 __ Push(allocation_site, argc); |
| 540 | 542 |
| 541 if (create_implicit_receiver) { | 543 if (create_implicit_receiver) { |
| 542 // sp[0]: new.target | 544 // Allocate the new receiver object. |
| 543 // sp[1]: Constructor function. | 545 __ Push(constructor, new_target); |
| 544 // sp[2]: number of arguments (smi-tagged) | 546 FastNewObjectStub stub(masm->isolate()); |
| 545 // sp[3]: allocation site | 547 __ CallStub(&stub); |
| 546 // Try to allocate the object without transitioning into C code. If any of | |
| 547 // the preconditions is not met, the code bails out to the runtime call. | |
| 548 Label rt_call, allocated; | |
| 549 if (FLAG_inline_new) { | |
| 550 // Verify that the new target is a JSFunction. | |
| 551 __ JumpIfNotObjectType(new_target, x10, x11, JS_FUNCTION_TYPE, | |
| 552 &rt_call); | |
| 553 | |
| 554 // Load the initial map and verify that it is in fact a map. | |
| 555 Register init_map = x2; | |
| 556 __ Ldr(init_map, | |
| 557 FieldMemOperand(new_target, | |
| 558 JSFunction::kPrototypeOrInitialMapOffset)); | |
| 559 __ JumpIfSmi(init_map, &rt_call); | |
| 560 __ JumpIfNotObjectType(init_map, x10, x11, MAP_TYPE, &rt_call); | |
| 561 | |
| 562 // Fall back to runtime if the expected base constructor and base | |
| 563 // constructor differ. | |
| 564 __ Ldr(x10, | |
| 565 FieldMemOperand(init_map, Map::kConstructorOrBackPointerOffset)); | |
| 566 __ Cmp(constructor, x10); | |
| 567 __ B(ne, &rt_call); | |
| 568 | |
| 569 // Check that the constructor is not constructing a JSFunction (see | |
| 570 // comments in Runtime_NewObject in runtime.cc). In which case the | |
| 571 // initial | |
| 572 // map's instance type would be JS_FUNCTION_TYPE. | |
| 573 __ CompareInstanceType(init_map, x10, JS_FUNCTION_TYPE); | |
| 574 __ B(eq, &rt_call); | |
| 575 | |
| 576 // Now allocate the JSObject on the heap. | |
| 577 Register obj_size = x10; | |
| 578 Register new_obj = x4; | |
| 579 Register next_obj = obj_size; // May overlap. | |
| 580 __ Ldrb(obj_size, FieldMemOperand(init_map, Map::kInstanceSizeOffset)); | |
| 581 __ Allocate(obj_size, new_obj, next_obj, x11, &rt_call, SIZE_IN_WORDS); | |
| 582 | |
| 583 // Allocated the JSObject, now initialize the fields. Map is set to | |
| 584 // initial map and properties and elements are set to empty fixed array. | |
| 585 // NB. the object pointer is not tagged, so MemOperand is used. | |
| 586 Register write_address = x5; | |
| 587 Register empty = x7; | |
| 588 __ Mov(write_address, new_obj); | |
| 589 __ LoadRoot(empty, Heap::kEmptyFixedArrayRootIndex); | |
| 590 STATIC_ASSERT(0 * kPointerSize == JSObject::kMapOffset); | |
| 591 __ Str(init_map, MemOperand(write_address, kPointerSize, PostIndex)); | |
| 592 STATIC_ASSERT(1 * kPointerSize == JSObject::kPropertiesOffset); | |
| 593 STATIC_ASSERT(2 * kPointerSize == JSObject::kElementsOffset); | |
| 594 __ Stp(empty, empty, | |
| 595 MemOperand(write_address, 2 * kPointerSize, PostIndex)); | |
| 596 STATIC_ASSERT(3 * kPointerSize == JSObject::kHeaderSize); | |
| 597 | |
| 598 // Add the object tag to make the JSObject real, so that we can continue | |
| 599 // and jump into the continuation code at any time from now on. | |
| 600 __ Add(new_obj, new_obj, kHeapObjectTag); | |
| 601 | |
| 602 // Fill all of the in-object properties with the appropriate filler. | |
| 603 Register filler = x7; | |
| 604 __ LoadRoot(filler, Heap::kUndefinedValueRootIndex); | |
| 605 | |
| 606 if (!is_api_function) { | |
| 607 Label no_inobject_slack_tracking; | |
| 608 | |
| 609 Register constructon_count = x14; | |
| 610 MemOperand bit_field3 = | |
| 611 FieldMemOperand(init_map, Map::kBitField3Offset); | |
| 612 // Check if slack tracking is enabled. | |
| 613 __ Ldr(x11, bit_field3); | |
| 614 __ DecodeField<Map::ConstructionCounter>(constructon_count, x11); | |
| 615 __ Cmp(constructon_count, Operand(Map::kSlackTrackingCounterEnd)); | |
| 616 __ B(lt, &no_inobject_slack_tracking); | |
| 617 // Decrease generous allocation count. | |
| 618 __ Subs(x11, x11, Operand(1 << Map::ConstructionCounter::kShift)); | |
| 619 __ Str(x11, bit_field3); | |
| 620 | |
| 621 // Allocate object with a slack. | |
| 622 Register unused_props = x11; | |
| 623 __ Ldr(unused_props, | |
| 624 FieldMemOperand(init_map, Map::kInstanceAttributesOffset)); | |
| 625 __ Ubfx(unused_props, unused_props, | |
| 626 Map::kUnusedPropertyFieldsByte * kBitsPerByte, kBitsPerByte); | |
| 627 | |
| 628 Register end_of_pre_allocated = x11; | |
| 629 __ Sub(end_of_pre_allocated, next_obj, | |
| 630 Operand(unused_props, LSL, kPointerSizeLog2)); | |
| 631 unused_props = NoReg; | |
| 632 | |
| 633 if (FLAG_debug_code) { | |
| 634 __ Cmp(write_address, end_of_pre_allocated); | |
| 635 __ Assert(le, kUnexpectedNumberOfPreAllocatedPropertyFields); | |
| 636 } | |
| 637 | |
| 638 // Fill the pre-allocated fields with undef. | |
| 639 __ InitializeFieldsWithFiller(write_address, end_of_pre_allocated, | |
| 640 filler); | |
| 641 | |
| 642 // Fill the remaining fields with one pointer filler map. | |
| 643 __ LoadRoot(filler, Heap::kOnePointerFillerMapRootIndex); | |
| 644 __ InitializeFieldsWithFiller(write_address, next_obj, filler); | |
| 645 | |
| 646 __ Cmp(constructon_count, Operand(Map::kSlackTrackingCounterEnd)); | |
| 647 __ B(ne, &allocated); | |
| 648 | |
| 649 // Push the constructor, new_target and the object to the stack, | |
| 650 // and then the initial map as an argument to the runtime call. | |
| 651 __ Push(constructor, new_target, new_obj, init_map); | |
| 652 __ CallRuntime(Runtime::kFinalizeInstanceSize); | |
| 653 __ Pop(new_obj, new_target, constructor); | |
| 654 | |
| 655 // Continue with JSObject being successfully allocated. | |
| 656 __ B(&allocated); | |
| 657 | |
| 658 __ bind(&no_inobject_slack_tracking); | |
| 659 } | |
| 660 | |
| 661 __ InitializeFieldsWithFiller(write_address, next_obj, filler); | |
| 662 | |
| 663 // Continue with JSObject being successfully allocated. | |
| 664 __ B(&allocated); | |
| 665 } | |
| 666 | |
| 667 // Allocate the new receiver object using the runtime call. | |
| 668 // x1: constructor function | |
| 669 // x3: new target | |
| 670 __ Bind(&rt_call); | |
| 671 | |
| 672 // Push the constructor and new_target twice, second pair as arguments | |
| 673 // to the runtime call. | |
| 674 __ Push(constructor, new_target, constructor, new_target); | |
| 675 __ CallRuntime(Runtime::kNewObject); | |
| 676 __ Mov(x4, x0); | 548 __ Mov(x4, x0); |
| 677 __ Pop(new_target, constructor); | 549 __ Pop(new_target, constructor); |
| 678 | 550 |
| 679 // Receiver for constructor call allocated. | 551 // ----------- S t a t e ------------- |
| 680 // x1: constructor function | 552 // -- x1: constructor function |
| 681 // x3: new target | 553 // -- x3: new target |
| 682 // x4: JSObject | 554 // -- x4: newly allocated object |
| 683 __ Bind(&allocated); | 555 // ----------------------------------- |
| 684 | 556 |
| 685 // Reload the number of arguments from the stack. | 557 // Reload the number of arguments from the stack. |
| 686 // Set it up in x0 for the function call below. | 558 // Set it up in x0 for the function call below. |
| 687 // jssp[0]: number of arguments (smi-tagged) | 559 // jssp[0]: number of arguments (smi-tagged) |
| 688 __ Peek(argc, 0); // Load number of arguments. | 560 __ Peek(argc, 0); // Load number of arguments. |
| 689 } | 561 } |
| 690 | 562 |
| 691 __ SmiUntag(argc); | 563 __ SmiUntag(argc); |
| 692 | 564 |
| 693 if (create_implicit_receiver) { | 565 if (create_implicit_receiver) { |
| (...skipping 2129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2823 } | 2695 } |
| 2824 } | 2696 } |
| 2825 | 2697 |
| 2826 | 2698 |
| 2827 #undef __ | 2699 #undef __ |
| 2828 | 2700 |
| 2829 } // namespace internal | 2701 } // namespace internal |
| 2830 } // namespace v8 | 2702 } // namespace v8 |
| 2831 | 2703 |
| 2832 #endif // V8_TARGET_ARCH_ARM | 2704 #endif // V8_TARGET_ARCH_ARM |
| OLD | NEW |