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