| OLD | NEW |
| 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 #if V8_TARGET_ARCH_MIPS64 | 5 #if V8_TARGET_ARCH_MIPS64 |
| 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 315 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 326 __ Branch(&new_object, ne, a1, Operand(a3)); | 326 __ Branch(&new_object, ne, a1, Operand(a3)); |
| 327 | 327 |
| 328 // 5. Allocate a JSValue wrapper for the number. | 328 // 5. Allocate a JSValue wrapper for the number. |
| 329 __ AllocateJSValue(v0, a1, a0, a2, t0, &new_object); | 329 __ AllocateJSValue(v0, a1, a0, a2, t0, &new_object); |
| 330 __ Ret(); | 330 __ Ret(); |
| 331 | 331 |
| 332 // 6. Fallback to the runtime to create new object. | 332 // 6. Fallback to the runtime to create new object. |
| 333 __ bind(&new_object); | 333 __ bind(&new_object); |
| 334 { | 334 { |
| 335 FrameScope scope(masm, StackFrame::INTERNAL); | 335 FrameScope scope(masm, StackFrame::INTERNAL); |
| 336 __ Push(a0, a1, a3); // first argument, constructor, new target | 336 __ Push(a0); |
| 337 __ CallRuntime(Runtime::kNewObject); | 337 FastNewObjectStub stub(masm->isolate()); |
| 338 __ CallStub(&stub); |
| 338 __ Pop(a0); | 339 __ Pop(a0); |
| 339 } | 340 } |
| 340 __ Ret(USE_DELAY_SLOT); | 341 __ Ret(USE_DELAY_SLOT); |
| 341 __ sd(a0, FieldMemOperand(v0, JSValue::kValueOffset)); // In delay slot. | 342 __ sd(a0, FieldMemOperand(v0, JSValue::kValueOffset)); // In delay slot. |
| 342 } | 343 } |
| 343 | 344 |
| 344 | 345 |
| 345 // static | 346 // static |
| 346 void Builtins::Generate_StringConstructor(MacroAssembler* masm) { | 347 void Builtins::Generate_StringConstructor(MacroAssembler* masm) { |
| 347 // ----------- S t a t e ------------- | 348 // ----------- S t a t e ------------- |
| (...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 453 __ Branch(&new_object, ne, a1, Operand(a3)); | 454 __ Branch(&new_object, ne, a1, Operand(a3)); |
| 454 | 455 |
| 455 // 5. Allocate a JSValue wrapper for the string. | 456 // 5. Allocate a JSValue wrapper for the string. |
| 456 __ AllocateJSValue(v0, a1, a0, a2, t0, &new_object); | 457 __ AllocateJSValue(v0, a1, a0, a2, t0, &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 FrameScope scope(masm, StackFrame::INTERNAL); | 463 FrameScope scope(masm, StackFrame::INTERNAL); |
| 463 __ Push(a0, a1, a3); // first argument, constructor, new target | 464 __ Push(a0); |
| 464 __ CallRuntime(Runtime::kNewObject); | 465 FastNewObjectStub stub(masm->isolate()); |
| 466 __ CallStub(&stub); |
| 465 __ Pop(a0); | 467 __ Pop(a0); |
| 466 } | 468 } |
| 467 __ Ret(USE_DELAY_SLOT); | 469 __ Ret(USE_DELAY_SLOT); |
| 468 __ sd(a0, FieldMemOperand(v0, JSValue::kValueOffset)); // In delay slot. | 470 __ sd(a0, FieldMemOperand(v0, JSValue::kValueOffset)); // In delay slot. |
| 469 } | 471 } |
| 470 | 472 |
| 471 static void GenerateTailCallToSharedCode(MacroAssembler* masm) { | 473 static void GenerateTailCallToSharedCode(MacroAssembler* masm) { |
| 472 __ ld(a2, FieldMemOperand(a1, JSFunction::kSharedFunctionInfoOffset)); | 474 __ ld(a2, FieldMemOperand(a1, JSFunction::kSharedFunctionInfoOffset)); |
| 473 __ ld(a2, FieldMemOperand(a2, SharedFunctionInfo::kCodeOffset)); | 475 __ ld(a2, FieldMemOperand(a2, SharedFunctionInfo::kCodeOffset)); |
| 474 __ Daddu(at, a2, Operand(Code::kHeaderSize - kHeapObjectTag)); | 476 __ Daddu(at, a2, Operand(Code::kHeaderSize - kHeapObjectTag)); |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 535 // Enter a construct frame. | 537 // Enter a construct frame. |
| 536 { | 538 { |
| 537 FrameScope scope(masm, StackFrame::CONSTRUCT); | 539 FrameScope scope(masm, StackFrame::CONSTRUCT); |
| 538 | 540 |
| 539 // Preserve the incoming parameters on the stack. | 541 // Preserve the incoming parameters on the stack. |
| 540 __ AssertUndefinedOrAllocationSite(a2, t0); | 542 __ AssertUndefinedOrAllocationSite(a2, t0); |
| 541 __ SmiTag(a0); | 543 __ SmiTag(a0); |
| 542 __ Push(a2, a0); | 544 __ Push(a2, a0); |
| 543 | 545 |
| 544 if (create_implicit_receiver) { | 546 if (create_implicit_receiver) { |
| 545 // Try to allocate the object without transitioning into C code. If any of | 547 __ Push(a1, a3); |
| 546 // the preconditions is not met, the code bails out to the runtime call. | 548 FastNewObjectStub stub(masm->isolate()); |
| 547 Label rt_call, allocated; | 549 __ CallStub(&stub); |
| 548 if (FLAG_inline_new) { | |
| 549 // Verify that the new target is a JSFunction. | |
| 550 __ GetObjectType(a3, a5, a4); | |
| 551 __ Branch(&rt_call, ne, a4, Operand(JS_FUNCTION_TYPE)); | |
| 552 | |
| 553 // Load the initial map and verify that it is in fact a map. | |
| 554 // a3: new target | |
| 555 __ ld(a2, | |
| 556 FieldMemOperand(a3, JSFunction::kPrototypeOrInitialMapOffset)); | |
| 557 __ JumpIfSmi(a2, &rt_call); | |
| 558 __ GetObjectType(a2, t1, t0); | |
| 559 __ Branch(&rt_call, ne, t0, Operand(MAP_TYPE)); | |
| 560 | |
| 561 // Fall back to runtime if the expected base constructor and base | |
| 562 // constructor differ. | |
| 563 __ ld(a5, FieldMemOperand(a2, Map::kConstructorOrBackPointerOffset)); | |
| 564 __ Branch(&rt_call, ne, a1, Operand(a5)); | |
| 565 | |
| 566 // Check that the constructor is not constructing a JSFunction (see | |
| 567 // comments in Runtime_NewObject in runtime.cc). In which case the | |
| 568 // initial map's instance type would be JS_FUNCTION_TYPE. | |
| 569 // a1: constructor function | |
| 570 // a2: initial map | |
| 571 __ lbu(t1, FieldMemOperand(a2, Map::kInstanceTypeOffset)); | |
| 572 __ Branch(&rt_call, eq, t1, Operand(JS_FUNCTION_TYPE)); | |
| 573 | |
| 574 // Now allocate the JSObject on the heap. | |
| 575 // a1: constructor function | |
| 576 // a2: initial map | |
| 577 __ lbu(a4, FieldMemOperand(a2, Map::kInstanceSizeOffset)); | |
| 578 __ Allocate(a4, t0, a4, t2, &rt_call, SIZE_IN_WORDS); | |
| 579 | |
| 580 // Allocated the JSObject, now initialize the fields. Map is set to | |
| 581 // initial map and properties and elements are set to empty fixed array. | |
| 582 // a1: constructor function | |
| 583 // a2: initial map | |
| 584 // a3: object size | |
| 585 // t0: JSObject (not HeapObject tagged - the actual address). | |
| 586 // a4: start of next object | |
| 587 __ LoadRoot(t2, Heap::kEmptyFixedArrayRootIndex); | |
| 588 __ mov(t1, t0); | |
| 589 STATIC_ASSERT(0 * kPointerSize == JSObject::kMapOffset); | |
| 590 __ sd(a2, MemOperand(t1, JSObject::kMapOffset)); | |
| 591 STATIC_ASSERT(1 * kPointerSize == JSObject::kPropertiesOffset); | |
| 592 __ sd(t2, MemOperand(t1, JSObject::kPropertiesOffset)); | |
| 593 STATIC_ASSERT(2 * kPointerSize == JSObject::kElementsOffset); | |
| 594 __ sd(t2, MemOperand(t1, JSObject::kElementsOffset)); | |
| 595 STATIC_ASSERT(3 * kPointerSize == JSObject::kHeaderSize); | |
| 596 __ Daddu(t1, t1, Operand(3 * kPointerSize)); | |
| 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 __ Daddu(t0, t0, Operand(kHeapObjectTag)); | |
| 601 | |
| 602 // Fill all the in-object properties with appropriate filler. | |
| 603 // t0: JSObject (tagged) | |
| 604 // t1: First in-object property of JSObject (not tagged) | |
| 605 __ LoadRoot(t3, Heap::kUndefinedValueRootIndex); | |
| 606 | |
| 607 if (!is_api_function) { | |
| 608 Label no_inobject_slack_tracking; | |
| 609 | |
| 610 MemOperand bit_field3 = FieldMemOperand(a2, Map::kBitField3Offset); | |
| 611 // Check if slack tracking is enabled. | |
| 612 __ lwu(t2, bit_field3); | |
| 613 __ DecodeField<Map::ConstructionCounter>(a6, t2); | |
| 614 // a6: slack tracking counter | |
| 615 __ Branch(&no_inobject_slack_tracking, lt, a6, | |
| 616 Operand(Map::kSlackTrackingCounterEnd)); | |
| 617 // Decrease generous allocation count. | |
| 618 __ Dsubu(t2, t2, Operand(1 << Map::ConstructionCounter::kShift)); | |
| 619 __ sw(t2, bit_field3); | |
| 620 | |
| 621 // Allocate object with a slack. | |
| 622 __ lbu(a0, FieldMemOperand(a2, Map::kUnusedPropertyFieldsOffset)); | |
| 623 __ dsll(a0, a0, kPointerSizeLog2); | |
| 624 __ dsubu(a0, a4, a0); | |
| 625 // a0: offset of first field after pre-allocated fields | |
| 626 if (FLAG_debug_code) { | |
| 627 __ Assert(le, kUnexpectedNumberOfPreAllocatedPropertyFields, t1, | |
| 628 Operand(a0)); | |
| 629 } | |
| 630 __ InitializeFieldsWithFiller(t1, a0, t3); | |
| 631 | |
| 632 // To allow truncation fill the remaining fields with one pointer | |
| 633 // filler map. | |
| 634 __ LoadRoot(t3, Heap::kOnePointerFillerMapRootIndex); | |
| 635 __ InitializeFieldsWithFiller(t1, a4, t3); | |
| 636 | |
| 637 // a6: slack tracking counter value before decreasing. | |
| 638 __ Branch(&allocated, ne, a6, Operand(Map::kSlackTrackingCounterEnd)); | |
| 639 | |
| 640 // Push the constructor, new_target and the object to the stack, | |
| 641 // and then the initial map as an argument to the runtime call. | |
| 642 __ Push(a1, a3, t0, a2); | |
| 643 __ CallRuntime(Runtime::kFinalizeInstanceSize); | |
| 644 __ Pop(a1, a3, t0); | |
| 645 | |
| 646 // Continue with JSObject being successfully allocated. | |
| 647 // a1: constructor function | |
| 648 // a3: new target | |
| 649 // t0: JSObject | |
| 650 __ jmp(&allocated); | |
| 651 | |
| 652 __ bind(&no_inobject_slack_tracking); | |
| 653 } | |
| 654 | |
| 655 __ InitializeFieldsWithFiller(t1, a4, t3); | |
| 656 | |
| 657 // Continue with JSObject being successfully allocated. | |
| 658 // a1: constructor function | |
| 659 // a3: new target | |
| 660 // t0: JSObject | |
| 661 __ jmp(&allocated); | |
| 662 } | |
| 663 | |
| 664 // Allocate the new receiver object using the runtime call. | |
| 665 // a1: constructor function | |
| 666 // a3: new target | |
| 667 __ bind(&rt_call); | |
| 668 | |
| 669 // Push the constructor and new_target twice, second pair as arguments | |
| 670 // to the runtime call. | |
| 671 __ Push(a1, a3, a1, a3); // constructor function, new target | |
| 672 __ CallRuntime(Runtime::kNewObject); | |
| 673 __ mov(t0, v0); | 550 __ mov(t0, v0); |
| 674 __ Pop(a1, a3); | 551 __ Pop(a1, a3); |
| 675 | 552 |
| 676 // Receiver for constructor call allocated. | 553 // ----------- S t a t e ------------- |
| 677 // a1: constructor function | 554 // -- a1: constructor function |
| 678 // a3: new target | 555 // -- a3: new target |
| 679 // t0: JSObject | 556 // -- t0: newly allocated object |
| 680 __ bind(&allocated); | 557 // ----------------------------------- |
| 681 | |
| 682 __ ld(a0, MemOperand(sp)); | 558 __ ld(a0, MemOperand(sp)); |
| 683 } | 559 } |
| 684 __ SmiUntag(a0); | 560 __ SmiUntag(a0); |
| 685 | 561 |
| 686 if (create_implicit_receiver) { | 562 if (create_implicit_receiver) { |
| 687 // Push the allocated receiver to the stack. We need two copies | 563 // Push the allocated receiver to the stack. We need two copies |
| 688 // because we may have to return the original one and the calling | 564 // because we may have to return the original one and the calling |
| 689 // conventions dictate that the called function pops the receiver. | 565 // conventions dictate that the called function pops the receiver. |
| 690 __ Push(t0, t0); | 566 __ Push(t0, t0); |
| 691 } else { | 567 } else { |
| (...skipping 2079 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2771 } | 2647 } |
| 2772 } | 2648 } |
| 2773 | 2649 |
| 2774 | 2650 |
| 2775 #undef __ | 2651 #undef __ |
| 2776 | 2652 |
| 2777 } // namespace internal | 2653 } // namespace internal |
| 2778 } // namespace v8 | 2654 } // namespace v8 |
| 2779 | 2655 |
| 2780 #endif // V8_TARGET_ARCH_MIPS64 | 2656 #endif // V8_TARGET_ARCH_MIPS64 |
| OLD | NEW |