| 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 | 5 |
| 6 | 6 |
| 7 #include "src/v8.h" | 7 #include "src/v8.h" |
| 8 | 8 |
| 9 #if V8_TARGET_ARCH_MIPS64 | 9 #if V8_TARGET_ARCH_MIPS64 |
| 10 | 10 |
| (...skipping 375 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 386 __ Branch(&normal_new, eq, a1, Operand(a3)); | 386 __ Branch(&normal_new, eq, a1, Operand(a3)); |
| 387 | 387 |
| 388 // Original constructor and function are different. | 388 // Original constructor and function are different. |
| 389 Generate_Runtime_NewObject(masm, create_memento, a3, &count_incremented, | 389 Generate_Runtime_NewObject(masm, create_memento, a3, &count_incremented, |
| 390 &allocated); | 390 &allocated); |
| 391 __ bind(&normal_new); | 391 __ bind(&normal_new); |
| 392 | 392 |
| 393 // Try to allocate the object without transitioning into C code. If any of | 393 // Try to allocate the object without transitioning into C code. If any of |
| 394 // the preconditions is not met, the code bails out to the runtime call. | 394 // the preconditions is not met, the code bails out to the runtime call. |
| 395 if (FLAG_inline_new) { | 395 if (FLAG_inline_new) { |
| 396 Label undo_allocation; | |
| 397 ExternalReference debug_step_in_fp = | 396 ExternalReference debug_step_in_fp = |
| 398 ExternalReference::debug_step_in_fp_address(isolate); | 397 ExternalReference::debug_step_in_fp_address(isolate); |
| 399 __ li(a2, Operand(debug_step_in_fp)); | 398 __ li(a2, Operand(debug_step_in_fp)); |
| 400 __ ld(a2, MemOperand(a2)); | 399 __ ld(a2, MemOperand(a2)); |
| 401 __ Branch(&rt_call, ne, a2, Operand(zero_reg)); | 400 __ Branch(&rt_call, ne, a2, Operand(zero_reg)); |
| 402 | 401 |
| 403 // Load the initial map and verify that it is in fact a map. | 402 // Load the initial map and verify that it is in fact a map. |
| 404 // a1: constructor function | 403 // a1: constructor function |
| 405 __ ld(a2, FieldMemOperand(a1, JSFunction::kPrototypeOrInitialMapOffset)); | 404 __ ld(a2, FieldMemOperand(a1, JSFunction::kPrototypeOrInitialMapOffset)); |
| 406 __ JumpIfSmi(a2, &rt_call); | 405 __ JumpIfSmi(a2, &rt_call); |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 478 | 477 |
| 479 if (!is_api_function) { | 478 if (!is_api_function) { |
| 480 Label no_inobject_slack_tracking; | 479 Label no_inobject_slack_tracking; |
| 481 | 480 |
| 482 // Check if slack tracking is enabled. | 481 // Check if slack tracking is enabled. |
| 483 __ Branch(&no_inobject_slack_tracking, lt, a6, | 482 __ Branch(&no_inobject_slack_tracking, lt, a6, |
| 484 Operand(static_cast<int64_t>(Map::kSlackTrackingCounterEnd))); | 483 Operand(static_cast<int64_t>(Map::kSlackTrackingCounterEnd))); |
| 485 | 484 |
| 486 // Allocate object with a slack. | 485 // Allocate object with a slack. |
| 487 __ lwu(a0, FieldMemOperand(a2, Map::kInstanceSizesOffset)); | 486 __ lwu(a0, FieldMemOperand(a2, Map::kInstanceSizesOffset)); |
| 488 __ Ext(a0, a0, Map::kPreAllocatedPropertyFieldsByte * kBitsPerByte, | 487 __ Ext(a0, a0, Map::kInObjectPropertiesByte * kBitsPerByte, |
| 489 kBitsPerByte); | 488 kBitsPerByte); |
| 489 __ lwu(a2, FieldMemOperand(a2, Map::kInstanceAttributesOffset)); |
| 490 __ Ext(a2, a2, Map::kUnusedPropertyFieldsByte * kBitsPerByte, |
| 491 kBitsPerByte); |
| 492 __ dsubu(a0, a0, a2); |
| 490 __ dsll(at, a0, kPointerSizeLog2); | 493 __ dsll(at, a0, kPointerSizeLog2); |
| 491 __ daddu(a0, t1, at); | 494 __ daddu(a0, t1, at); |
| 492 // a0: offset of first field after pre-allocated fields | 495 // a0: offset of first field after pre-allocated fields |
| 493 if (FLAG_debug_code) { | 496 if (FLAG_debug_code) { |
| 494 __ dsll(at, a3, kPointerSizeLog2); | 497 __ dsll(at, a3, kPointerSizeLog2); |
| 495 __ Daddu(t2, t0, Operand(at)); // End of object. | 498 __ Daddu(t2, t0, Operand(at)); // End of object. |
| 496 __ Assert(le, kUnexpectedNumberOfPreAllocatedPropertyFields, | 499 __ Assert(le, kUnexpectedNumberOfPreAllocatedPropertyFields, |
| 497 a0, Operand(t2)); | 500 a0, Operand(t2)); |
| 498 } | 501 } |
| 499 __ InitializeFieldsWithFiller(t1, a0, t3); | 502 __ InitializeFieldsWithFiller(t1, a0, t3); |
| (...skipping 21 matching lines...) Expand all Loading... |
| 521 DCHECK_EQ(1 * kPointerSize, AllocationMemento::kAllocationSiteOffset); | 524 DCHECK_EQ(1 * kPointerSize, AllocationMemento::kAllocationSiteOffset); |
| 522 __ sd(t3, MemOperand(t1)); | 525 __ sd(t3, MemOperand(t1)); |
| 523 __ Daddu(t1, t1, kPointerSize); | 526 __ Daddu(t1, t1, kPointerSize); |
| 524 } else { | 527 } else { |
| 525 __ dsll(at, a3, kPointerSizeLog2); | 528 __ dsll(at, a3, kPointerSizeLog2); |
| 526 __ Daddu(a0, t0, Operand(at)); // End of object. | 529 __ Daddu(a0, t0, Operand(at)); // End of object. |
| 527 __ InitializeFieldsWithFiller(t1, a0, t3); | 530 __ InitializeFieldsWithFiller(t1, a0, t3); |
| 528 } | 531 } |
| 529 | 532 |
| 530 // Add the object tag to make the JSObject real, so that we can continue | 533 // Add the object tag to make the JSObject real, so that we can continue |
| 531 // and jump into the continuation code at any time from now on. Any | 534 // and jump into the continuation code at any time from now on. |
| 532 // failures need to undo the allocation, so that the heap is in a | |
| 533 // consistent state and verifiable. | |
| 534 __ Daddu(t0, t0, Operand(kHeapObjectTag)); | 535 __ Daddu(t0, t0, Operand(kHeapObjectTag)); |
| 535 | 536 |
| 536 // Check if a non-empty properties array is needed. Continue with | |
| 537 // allocated object if not; allocate and initialize a FixedArray if yes. | |
| 538 // a1: constructor function | |
| 539 // t0: JSObject | |
| 540 // t1: start of next object (not tagged) | |
| 541 __ lbu(a3, FieldMemOperand(a2, Map::kUnusedPropertyFieldsOffset)); | |
| 542 // The field instance sizes contains both pre-allocated property fields | |
| 543 // and in-object properties. | |
| 544 __ lw(a0, FieldMemOperand(a2, Map::kInstanceSizesOffset)); | |
| 545 __ Ext(t2, a0, Map::kPreAllocatedPropertyFieldsByte * kBitsPerByte, | |
| 546 kBitsPerByte); | |
| 547 __ Daddu(a3, a3, Operand(t2)); | |
| 548 __ Ext(t2, a0, Map::kInObjectPropertiesByte * kBitsPerByte, | |
| 549 kBitsPerByte); | |
| 550 __ dsubu(a3, a3, t2); | |
| 551 | |
| 552 // Done if no extra properties are to be allocated. | |
| 553 __ Branch(&allocated, eq, a3, Operand(zero_reg)); | |
| 554 __ Assert(greater_equal, kPropertyAllocationCountFailed, | |
| 555 a3, Operand(zero_reg)); | |
| 556 | |
| 557 // Scale the number of elements by pointer size and add the header for | |
| 558 // FixedArrays to the start of the next object calculation from above. | |
| 559 // a1: constructor | |
| 560 // a3: number of elements in properties array | |
| 561 // t0: JSObject | |
| 562 // t1: start of next object | |
| 563 __ Daddu(a0, a3, Operand(FixedArray::kHeaderSize / kPointerSize)); | |
| 564 __ Allocate( | |
| 565 a0, | |
| 566 t1, | |
| 567 t2, | |
| 568 a2, | |
| 569 &undo_allocation, | |
| 570 static_cast<AllocationFlags>(RESULT_CONTAINS_TOP | SIZE_IN_WORDS)); | |
| 571 | |
| 572 // Initialize the FixedArray. | |
| 573 // a1: constructor | |
| 574 // a3: number of elements in properties array (untagged) | |
| 575 // t0: JSObject | |
| 576 // t1: start of FixedArray (untagged) | |
| 577 __ LoadRoot(t2, Heap::kFixedArrayMapRootIndex); | |
| 578 __ mov(a2, t1); | |
| 579 __ sd(t2, MemOperand(a2, JSObject::kMapOffset)); | |
| 580 // Tag number of elements. | |
| 581 __ dsll32(a0, a3, 0); | |
| 582 __ sd(a0, MemOperand(a2, FixedArray::kLengthOffset)); | |
| 583 __ Daddu(a2, a2, Operand(2 * kPointerSize)); | |
| 584 | |
| 585 DCHECK_EQ(0 * kPointerSize, JSObject::kMapOffset); | |
| 586 DCHECK_EQ(1 * kPointerSize, FixedArray::kLengthOffset); | |
| 587 | |
| 588 // Initialize the fields to undefined. | |
| 589 // a1: constructor | |
| 590 // a2: First element of FixedArray (not tagged) | |
| 591 // a3: number of elements in properties array | |
| 592 // t0: JSObject | |
| 593 // t1: FixedArray (not tagged) | |
| 594 __ dsll(a7, a3, kPointerSizeLog2); | |
| 595 __ daddu(t2, a2, a7); // End of object. | |
| 596 DCHECK_EQ(2 * kPointerSize, FixedArray::kHeaderSize); | |
| 597 if (!is_api_function || create_memento) { | |
| 598 __ LoadRoot(t3, Heap::kUndefinedValueRootIndex); | |
| 599 } else if (FLAG_debug_code) { | |
| 600 __ LoadRoot(a6, Heap::kUndefinedValueRootIndex); | |
| 601 __ Assert(eq, kUndefinedValueNotLoaded, t3, Operand(a6)); | |
| 602 } | |
| 603 __ InitializeFieldsWithFiller(a2, t2, t3); | |
| 604 | |
| 605 // Store the initialized FixedArray into the properties field of | |
| 606 // the JSObject. | |
| 607 // a1: constructor function | |
| 608 // t0: JSObject | |
| 609 // t1: FixedArray (not tagged) | |
| 610 __ Daddu(t1, t1, Operand(kHeapObjectTag)); // Add the heap tag. | |
| 611 __ sd(t1, FieldMemOperand(t0, JSObject::kPropertiesOffset)); | |
| 612 | |
| 613 // Continue with JSObject being successfully allocated. | 537 // Continue with JSObject being successfully allocated. |
| 614 // a1: constructor function | |
| 615 // a4: JSObject | 538 // a4: JSObject |
| 616 __ jmp(&allocated); | 539 __ jmp(&allocated); |
| 617 | |
| 618 // Undo the setting of the new top so that the heap is verifiable. For | |
| 619 // example, the map's unused properties potentially do not match the | |
| 620 // allocated objects unused properties. | |
| 621 // t0: JSObject (previous new top) | |
| 622 __ bind(&undo_allocation); | |
| 623 __ UndoAllocationInNewSpace(t0, t1); | |
| 624 } | 540 } |
| 625 | 541 |
| 626 // Allocate the new receiver object using the runtime call. | 542 // Allocate the new receiver object using the runtime call. |
| 627 // a1: constructor function | 543 // a1: constructor function |
| 628 __ bind(&rt_call); | 544 __ bind(&rt_call); |
| 629 Generate_Runtime_NewObject(masm, create_memento, a1, &count_incremented, | 545 Generate_Runtime_NewObject(masm, create_memento, a1, &count_incremented, |
| 630 &allocated); | 546 &allocated); |
| 631 | 547 |
| 632 | 548 |
| 633 // Receiver for constructor call allocated. | 549 // Receiver for constructor call allocated. |
| (...skipping 1208 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1842 } | 1758 } |
| 1843 } | 1759 } |
| 1844 | 1760 |
| 1845 | 1761 |
| 1846 #undef __ | 1762 #undef __ |
| 1847 | 1763 |
| 1848 } // namespace internal | 1764 } // namespace internal |
| 1849 } // namespace v8 | 1765 } // namespace v8 |
| 1850 | 1766 |
| 1851 #endif // V8_TARGET_ARCH_MIPS64 | 1767 #endif // V8_TARGET_ARCH_MIPS64 |
| OLD | NEW |