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_ARM | 5 #if V8_TARGET_ARCH_ARM |
6 | 6 |
7 #include "src/base/bits.h" | 7 #include "src/base/bits.h" |
8 #include "src/bootstrapper.h" | 8 #include "src/bootstrapper.h" |
9 #include "src/code-stubs.h" | 9 #include "src/code-stubs.h" |
10 #include "src/codegen.h" | 10 #include "src/codegen.h" |
(...skipping 4543 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4554 Label fast_elements_case; | 4554 Label fast_elements_case; |
4555 __ cmp(r3, Operand(FAST_ELEMENTS)); | 4555 __ cmp(r3, Operand(FAST_ELEMENTS)); |
4556 __ b(eq, &fast_elements_case); | 4556 __ b(eq, &fast_elements_case); |
4557 GenerateCase(masm, FAST_HOLEY_ELEMENTS); | 4557 GenerateCase(masm, FAST_HOLEY_ELEMENTS); |
4558 | 4558 |
4559 __ bind(&fast_elements_case); | 4559 __ bind(&fast_elements_case); |
4560 GenerateCase(masm, FAST_ELEMENTS); | 4560 GenerateCase(masm, FAST_ELEMENTS); |
4561 } | 4561 } |
4562 | 4562 |
4563 | 4563 |
| 4564 void FastNewObjectStub::Generate(MacroAssembler* masm) { |
| 4565 // ----------- S t a t e ------------- |
| 4566 // -- r1 : target |
| 4567 // -- r3 : new target |
| 4568 // -- cp : context |
| 4569 // -- lr : return address |
| 4570 // ----------------------------------- |
| 4571 __ AssertFunction(r1); |
| 4572 __ AssertReceiver(r3); |
| 4573 |
| 4574 // Verify that the new target is a JSFunction. |
| 4575 Label new_object; |
| 4576 __ CompareObjectType(r3, r2, r2, JS_FUNCTION_TYPE); |
| 4577 __ b(ne, &new_object); |
| 4578 |
| 4579 // Load the initial map and verify that it's in fact a map. |
| 4580 __ ldr(r2, FieldMemOperand(r3, JSFunction::kPrototypeOrInitialMapOffset)); |
| 4581 __ JumpIfSmi(r2, &new_object); |
| 4582 __ CompareObjectType(r2, r0, r0, MAP_TYPE); |
| 4583 __ b(ne, &new_object); |
| 4584 |
| 4585 // Fall back to runtime if the target differs from the new target's |
| 4586 // initial map constructor. |
| 4587 __ ldr(r0, FieldMemOperand(r2, Map::kConstructorOrBackPointerOffset)); |
| 4588 __ cmp(r0, r1); |
| 4589 __ b(ne, &new_object); |
| 4590 |
| 4591 // Allocate the JSObject on the heap. |
| 4592 Label allocate, done_allocate; |
| 4593 __ ldrb(r4, FieldMemOperand(r2, Map::kInstanceSizeOffset)); |
| 4594 __ Allocate(r4, r0, r5, r6, &allocate, SIZE_IN_WORDS); |
| 4595 __ bind(&done_allocate); |
| 4596 |
| 4597 // Initialize the JSObject fields. |
| 4598 __ str(r2, MemOperand(r0, JSObject::kMapOffset)); |
| 4599 __ LoadRoot(r3, Heap::kEmptyFixedArrayRootIndex); |
| 4600 __ str(r3, MemOperand(r0, JSObject::kPropertiesOffset)); |
| 4601 __ str(r3, MemOperand(r0, JSObject::kElementsOffset)); |
| 4602 STATIC_ASSERT(JSObject::kHeaderSize == 3 * kPointerSize); |
| 4603 __ add(r1, r0, Operand(JSObject::kHeaderSize)); |
| 4604 |
| 4605 // ----------- S t a t e ------------- |
| 4606 // -- r0 : result (untagged) |
| 4607 // -- r1 : result fields (untagged) |
| 4608 // -- r5 : result end (untagged) |
| 4609 // -- r2 : initial map |
| 4610 // -- cp : context |
| 4611 // -- lr : return address |
| 4612 // ----------------------------------- |
| 4613 |
| 4614 // Perform in-object slack tracking if requested. |
| 4615 Label slack_tracking; |
| 4616 STATIC_ASSERT(Map::kNoSlackTracking == 0); |
| 4617 __ LoadRoot(r6, Heap::kUndefinedValueRootIndex); |
| 4618 __ ldr(r3, FieldMemOperand(r2, Map::kBitField3Offset)); |
| 4619 __ tst(r3, Operand(Map::ConstructionCounter::kMask)); |
| 4620 __ b(ne, &slack_tracking); |
| 4621 { |
| 4622 // Initialize all in-object fields with undefined. |
| 4623 __ InitializeFieldsWithFiller(r1, r5, r6); |
| 4624 |
| 4625 // Add the object tag to make the JSObject real. |
| 4626 STATIC_ASSERT(kHeapObjectTag == 1); |
| 4627 __ add(r0, r0, Operand(kHeapObjectTag)); |
| 4628 __ Ret(); |
| 4629 } |
| 4630 __ bind(&slack_tracking); |
| 4631 { |
| 4632 // Decrease generous allocation count. |
| 4633 STATIC_ASSERT(Map::ConstructionCounter::kNext == 32); |
| 4634 __ sub(r3, r3, Operand(1 << Map::ConstructionCounter::kShift)); |
| 4635 __ str(r3, FieldMemOperand(r2, Map::kBitField3Offset)); |
| 4636 |
| 4637 // Initialize the in-object fields with undefined. |
| 4638 __ ldrb(r4, FieldMemOperand(r2, Map::kUnusedPropertyFieldsOffset)); |
| 4639 __ sub(r4, r5, Operand(r4, LSL, kPointerSizeLog2)); |
| 4640 __ InitializeFieldsWithFiller(r1, r4, r6); |
| 4641 |
| 4642 // Initialize the remaining (reserved) fields with one pointer filler map. |
| 4643 __ LoadRoot(r6, Heap::kOnePointerFillerMapRootIndex); |
| 4644 __ InitializeFieldsWithFiller(r1, r5, r6); |
| 4645 |
| 4646 // Add the object tag to make the JSObject real. |
| 4647 STATIC_ASSERT(kHeapObjectTag == 1); |
| 4648 __ add(r0, r0, Operand(kHeapObjectTag)); |
| 4649 |
| 4650 // Check if we can finalize the instance size. |
| 4651 STATIC_ASSERT(Map::kSlackTrackingCounterEnd == 1); |
| 4652 __ tst(r3, Operand(Map::ConstructionCounter::kMask)); |
| 4653 __ Ret(ne); |
| 4654 |
| 4655 // Finalize the instance size. |
| 4656 { |
| 4657 FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL); |
| 4658 __ Push(r0, r2); |
| 4659 __ CallRuntime(Runtime::kFinalizeInstanceSize); |
| 4660 __ Pop(r0); |
| 4661 } |
| 4662 __ Ret(); |
| 4663 } |
| 4664 |
| 4665 // Fall back to %AllocateInNewSpace. |
| 4666 __ bind(&allocate); |
| 4667 { |
| 4668 FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL); |
| 4669 STATIC_ASSERT(kSmiTag == 0); |
| 4670 STATIC_ASSERT(kSmiTagSize == 1); |
| 4671 __ mov(r4, Operand(r4, LSL, kPointerSizeLog2 + 1)); |
| 4672 __ Push(r2, r4); |
| 4673 __ CallRuntime(Runtime::kAllocateInNewSpace); |
| 4674 __ Pop(r2); |
| 4675 } |
| 4676 STATIC_ASSERT(kHeapObjectTag == 1); |
| 4677 __ sub(r0, r0, Operand(kHeapObjectTag)); |
| 4678 __ ldrb(r5, FieldMemOperand(r2, Map::kInstanceSizeOffset)); |
| 4679 __ add(r5, r0, Operand(r5, LSL, kPointerSizeLog2)); |
| 4680 __ b(&done_allocate); |
| 4681 |
| 4682 // Fall back to %NewObject. |
| 4683 __ bind(&new_object); |
| 4684 __ Push(r1, r3); |
| 4685 __ TailCallRuntime(Runtime::kNewObject); |
| 4686 } |
| 4687 |
| 4688 |
4564 void FastNewRestParameterStub::Generate(MacroAssembler* masm) { | 4689 void FastNewRestParameterStub::Generate(MacroAssembler* masm) { |
4565 // ----------- S t a t e ------------- | 4690 // ----------- S t a t e ------------- |
4566 // -- r1 : function | 4691 // -- r1 : function |
4567 // -- cp : context | 4692 // -- cp : context |
4568 // -- fp : frame pointer | 4693 // -- fp : frame pointer |
4569 // -- lr : return address | 4694 // -- lr : return address |
4570 // ----------------------------------- | 4695 // ----------------------------------- |
4571 __ AssertFunction(r1); | 4696 __ AssertFunction(r1); |
4572 | 4697 |
4573 // For Ignition we need to skip all possible handler/stub frames until | 4698 // For Ignition we need to skip all possible handler/stub frames until |
(...skipping 913 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5487 kStackUnwindSpace, NULL, return_value_operand, NULL); | 5612 kStackUnwindSpace, NULL, return_value_operand, NULL); |
5488 } | 5613 } |
5489 | 5614 |
5490 | 5615 |
5491 #undef __ | 5616 #undef __ |
5492 | 5617 |
5493 } // namespace internal | 5618 } // namespace internal |
5494 } // namespace v8 | 5619 } // namespace v8 |
5495 | 5620 |
5496 #endif // V8_TARGET_ARCH_ARM | 5621 #endif // V8_TARGET_ARCH_ARM |
OLD | NEW |