| OLD | NEW |
| 1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 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_PPC | 5 #if V8_TARGET_ARCH_PPC |
| 6 | 6 |
| 7 #include "src/codegen.h" | 7 #include "src/codegen.h" |
| 8 #include "src/debug/debug.h" | 8 #include "src/debug/debug.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 313 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 324 __ bne(&new_object); | 324 __ bne(&new_object); |
| 325 | 325 |
| 326 // 5. Allocate a JSValue wrapper for the number. | 326 // 5. Allocate a JSValue wrapper for the number. |
| 327 __ AllocateJSValue(r3, r4, r5, r7, r8, &new_object); | 327 __ AllocateJSValue(r3, r4, r5, r7, r8, &new_object); |
| 328 __ Ret(); | 328 __ Ret(); |
| 329 | 329 |
| 330 // 6. Fallback to the runtime to create new object. | 330 // 6. Fallback to the runtime to create new object. |
| 331 __ bind(&new_object); | 331 __ bind(&new_object); |
| 332 { | 332 { |
| 333 FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL); | 333 FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL); |
| 334 __ Push(r5, r4, r6); // first argument, constructor, new target | 334 __ Push(r5); // first argument |
| 335 __ CallRuntime(Runtime::kNewObject); | 335 FastNewObjectStub stub(masm->isolate()); |
| 336 __ CallStub(&stub); |
| 336 __ Pop(r5); | 337 __ Pop(r5); |
| 337 } | 338 } |
| 338 __ StoreP(r5, FieldMemOperand(r3, JSValue::kValueOffset), r0); | 339 __ StoreP(r5, FieldMemOperand(r3, JSValue::kValueOffset), r0); |
| 339 __ Ret(); | 340 __ Ret(); |
| 340 } | 341 } |
| 341 | 342 |
| 342 | 343 |
| 343 // static | 344 // static |
| 344 void Builtins::Generate_StringConstructor(MacroAssembler* masm) { | 345 void Builtins::Generate_StringConstructor(MacroAssembler* masm) { |
| 345 // ----------- S t a t e ------------- | 346 // ----------- S t a t e ------------- |
| (...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 453 __ bne(&new_object); | 454 __ bne(&new_object); |
| 454 | 455 |
| 455 // 5. Allocate a JSValue wrapper for the string. | 456 // 5. Allocate a JSValue wrapper for the string. |
| 456 __ AllocateJSValue(r3, r4, r5, r7, r8, &new_object); | 457 __ AllocateJSValue(r3, r4, r5, r7, r8, &new_object); |
| 457 __ Ret(); | 458 __ Ret(); |
| 458 | 459 |
| 459 // 6. Fallback to the runtime to create new object. | 460 // 6. Fallback to the runtime to create new object. |
| 460 __ bind(&new_object); | 461 __ bind(&new_object); |
| 461 { | 462 { |
| 462 FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL); | 463 FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL); |
| 463 __ Push(r5, r4, r6); // first argument, constructor, new target | 464 __ Push(r5); // first argument |
| 464 __ CallRuntime(Runtime::kNewObject); | 465 FastNewObjectStub stub(masm->isolate()); |
| 466 __ CallStub(&stub); |
| 465 __ Pop(r5); | 467 __ Pop(r5); |
| 466 } | 468 } |
| 467 __ StoreP(r5, FieldMemOperand(r3, JSValue::kValueOffset), r0); | 469 __ StoreP(r5, FieldMemOperand(r3, JSValue::kValueOffset), r0); |
| 468 __ Ret(); | 470 __ Ret(); |
| 469 } | 471 } |
| 470 | 472 |
| 471 | 473 |
| 472 static void GenerateTailCallToSharedCode(MacroAssembler* masm) { | 474 static void GenerateTailCallToSharedCode(MacroAssembler* masm) { |
| 473 __ LoadP(ip, FieldMemOperand(r4, JSFunction::kSharedFunctionInfoOffset)); | 475 __ LoadP(ip, FieldMemOperand(r4, JSFunction::kSharedFunctionInfoOffset)); |
| 474 __ LoadP(ip, FieldMemOperand(ip, SharedFunctionInfo::kCodeOffset)); | 476 __ LoadP(ip, FieldMemOperand(ip, SharedFunctionInfo::kCodeOffset)); |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 544 __ AssertUndefinedOrAllocationSite(r5, r7); | 546 __ AssertUndefinedOrAllocationSite(r5, r7); |
| 545 | 547 |
| 546 if (!create_implicit_receiver) { | 548 if (!create_implicit_receiver) { |
| 547 __ SmiTag(r7, r3, SetRC); | 549 __ SmiTag(r7, r3, SetRC); |
| 548 __ Push(r5, r7); | 550 __ Push(r5, r7); |
| 549 __ PushRoot(Heap::kTheHoleValueRootIndex); | 551 __ PushRoot(Heap::kTheHoleValueRootIndex); |
| 550 } else { | 552 } else { |
| 551 __ SmiTag(r3); | 553 __ SmiTag(r3); |
| 552 __ Push(r5, r3); | 554 __ Push(r5, r3); |
| 553 | 555 |
| 554 // Try to allocate the object without transitioning into C code. If any of | 556 // Allocate the new receiver object. |
| 555 // the preconditions is not met, the code bails out to the runtime call. | 557 __ Push(r4, r6); |
| 556 Label rt_call, allocated; | 558 FastNewObjectStub stub(masm->isolate()); |
| 557 if (FLAG_inline_new) { | 559 __ CallStub(&stub); |
| 558 // Verify that the new target is a JSFunction. | |
| 559 __ CompareObjectType(r6, r8, r7, JS_FUNCTION_TYPE); | |
| 560 __ bne(&rt_call); | |
| 561 | |
| 562 // Load the initial map and verify that it is in fact a map. | |
| 563 // r6: new target | |
| 564 __ LoadP(r5, | |
| 565 FieldMemOperand(r6, JSFunction::kPrototypeOrInitialMapOffset)); | |
| 566 __ JumpIfSmi(r5, &rt_call); | |
| 567 __ CompareObjectType(r5, r8, r7, MAP_TYPE); | |
| 568 __ bne(&rt_call); | |
| 569 | |
| 570 // Fall back to runtime if the expected base constructor and base | |
| 571 // constructor differ. | |
| 572 __ LoadP(r8, FieldMemOperand(r5, Map::kConstructorOrBackPointerOffset)); | |
| 573 __ cmp(r4, r8); | |
| 574 __ bne(&rt_call); | |
| 575 | |
| 576 // Check that the constructor is not constructing a JSFunction (see | |
| 577 // comments in Runtime_NewObject in runtime.cc). In which case the | |
| 578 // initial map's instance type would be JS_FUNCTION_TYPE. | |
| 579 // r4: constructor function | |
| 580 // r5: initial map | |
| 581 // r6: new target | |
| 582 __ CompareInstanceType(r5, r8, JS_FUNCTION_TYPE); | |
| 583 __ beq(&rt_call); | |
| 584 | |
| 585 // Now allocate the JSObject on the heap. | |
| 586 // r4: constructor function | |
| 587 // r5: initial map | |
| 588 // r6: new target | |
| 589 __ lbz(r10, FieldMemOperand(r5, Map::kInstanceSizeOffset)); | |
| 590 | |
| 591 __ Allocate(r10, r7, r10, r9, &rt_call, SIZE_IN_WORDS); | |
| 592 | |
| 593 // Allocated the JSObject, now initialize the fields. Map is set to | |
| 594 // initial map and properties and elements are set to empty fixed array. | |
| 595 // r4: constructor function | |
| 596 // r5: initial map | |
| 597 // r6: new target | |
| 598 // r7: JSObject (not HeapObject tagged - the actual address). | |
| 599 // r10: start of next object | |
| 600 __ LoadRoot(r9, Heap::kEmptyFixedArrayRootIndex); | |
| 601 __ StoreP(r5, MemOperand(r7, JSObject::kMapOffset)); | |
| 602 __ StoreP(r9, MemOperand(r7, JSObject::kPropertiesOffset)); | |
| 603 __ StoreP(r9, MemOperand(r7, JSObject::kElementsOffset)); | |
| 604 __ addi(r8, r7, Operand(JSObject::kElementsOffset + kPointerSize)); | |
| 605 | |
| 606 // Add the object tag to make the JSObject real, so that we can continue | |
| 607 // and jump into the continuation code at any time from now on. | |
| 608 __ addi(r7, r7, Operand(kHeapObjectTag)); | |
| 609 | |
| 610 // Fill all the in-object properties with the appropriate filler. | |
| 611 // r7: JSObject (tagged) | |
| 612 // r8: First in-object property of JSObject (not tagged) | |
| 613 __ LoadRoot(r9, Heap::kUndefinedValueRootIndex); | |
| 614 | |
| 615 if (!is_api_function) { | |
| 616 Label no_inobject_slack_tracking; | |
| 617 | |
| 618 MemOperand bit_field3 = FieldMemOperand(r5, Map::kBitField3Offset); | |
| 619 // Check if slack tracking is enabled. | |
| 620 __ lwz(r3, bit_field3); | |
| 621 __ DecodeField<Map::ConstructionCounter>(r11, r3); | |
| 622 // r11: slack tracking counter | |
| 623 __ cmpi(r11, Operand(Map::kSlackTrackingCounterEnd)); | |
| 624 __ blt(&no_inobject_slack_tracking); | |
| 625 // Decrease generous allocation count. | |
| 626 __ Add(r3, r3, -(1 << Map::ConstructionCounter::kShift), r0); | |
| 627 __ stw(r3, bit_field3); | |
| 628 | |
| 629 // Allocate object with a slack. | |
| 630 __ lbz(r3, FieldMemOperand(r5, Map::kUnusedPropertyFieldsOffset)); | |
| 631 __ ShiftLeftImm(r3, r3, Operand(kPointerSizeLog2)); | |
| 632 __ sub(r3, r10, r3); | |
| 633 // r3: offset of first field after pre-allocated fields | |
| 634 if (FLAG_debug_code) { | |
| 635 __ cmp(r8, r3); | |
| 636 __ Assert(le, kUnexpectedNumberOfPreAllocatedPropertyFields); | |
| 637 } | |
| 638 __ InitializeFieldsWithFiller(r8, r3, r9); | |
| 639 | |
| 640 // To allow truncation fill the remaining fields with one pointer | |
| 641 // filler map. | |
| 642 __ LoadRoot(r9, Heap::kOnePointerFillerMapRootIndex); | |
| 643 __ InitializeFieldsWithFiller(r8, r10, r9); | |
| 644 | |
| 645 // r11: slack tracking counter value before decreasing. | |
| 646 __ cmpi(r11, Operand(Map::kSlackTrackingCounterEnd)); | |
| 647 __ bne(&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(r4, r6, r7, r5); | |
| 652 __ CallRuntime(Runtime::kFinalizeInstanceSize); | |
| 653 __ Pop(r4, r6, r7); | |
| 654 | |
| 655 // Continue with JSObject being successfully allocated | |
| 656 // r4: constructor function | |
| 657 // r6: new target | |
| 658 // r7: JSObject | |
| 659 __ b(&allocated); | |
| 660 | |
| 661 __ bind(&no_inobject_slack_tracking); | |
| 662 } | |
| 663 | |
| 664 __ InitializeFieldsWithFiller(r8, r10, r9); | |
| 665 | |
| 666 // Continue with JSObject being successfully allocated | |
| 667 // r4: constructor function | |
| 668 // r6: new target | |
| 669 // r7: JSObject | |
| 670 __ b(&allocated); | |
| 671 } | |
| 672 | |
| 673 // Allocate the new receiver object using the runtime call. | |
| 674 // r4: constructor function | |
| 675 // r6: new target | |
| 676 __ bind(&rt_call); | |
| 677 | |
| 678 // Push the constructor and new_target twice, second pair as arguments | |
| 679 // to the runtime call. | |
| 680 __ Push(r4, r6, r4, r6); | |
| 681 __ CallRuntime(Runtime::kNewObject); | |
| 682 __ mr(r7, r3); | 560 __ mr(r7, r3); |
| 683 __ Pop(r4, r6); | 561 __ Pop(r4, r6); |
| 684 | 562 |
| 685 // Receiver for constructor call allocated. | 563 // ----------- S t a t e ------------- |
| 686 // r4: constructor function | 564 // -- r4: constructor function |
| 687 // r6: new target | 565 // -- r6: new target |
| 688 // r7: JSObject | 566 // -- r7: newly allocated object |
| 689 __ bind(&allocated); | 567 // ----------------------------------- |
| 690 | 568 |
| 691 // Retrieve smi-tagged arguments count from the stack. | 569 // Retrieve smi-tagged arguments count from the stack. |
| 692 __ LoadP(r3, MemOperand(sp)); | 570 __ LoadP(r3, MemOperand(sp)); |
| 693 __ SmiUntag(r3, SetRC); | 571 __ SmiUntag(r3, SetRC); |
| 694 | 572 |
| 695 // Push the allocated receiver to the stack. We need two copies | 573 // Push the allocated receiver to the stack. We need two copies |
| 696 // because we may have to return the original one and the calling | 574 // because we may have to return the original one and the calling |
| 697 // conventions dictate that the called function pops the receiver. | 575 // conventions dictate that the called function pops the receiver. |
| 698 __ Push(r7, r7); | 576 __ Push(r7, r7); |
| 699 } | 577 } |
| (...skipping 2061 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2761 __ bkpt(0); | 2639 __ bkpt(0); |
| 2762 } | 2640 } |
| 2763 } | 2641 } |
| 2764 | 2642 |
| 2765 | 2643 |
| 2766 #undef __ | 2644 #undef __ |
| 2767 } // namespace internal | 2645 } // namespace internal |
| 2768 } // namespace v8 | 2646 } // namespace v8 |
| 2769 | 2647 |
| 2770 #endif // V8_TARGET_ARCH_PPC | 2648 #endif // V8_TARGET_ARCH_PPC |
| OLD | NEW |