OLD | NEW |
1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 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_X64 | 5 #if V8_TARGET_ARCH_X64 |
6 | 6 |
7 #include "src/code-stubs.h" | 7 #include "src/code-stubs.h" |
8 #include "src/api-arguments.h" | 8 #include "src/api-arguments.h" |
9 #include "src/bootstrapper.h" | 9 #include "src/bootstrapper.h" |
10 #include "src/codegen.h" | 10 #include "src/codegen.h" |
(...skipping 4431 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4442 __ j(not_equal, &new_object); | 4442 __ j(not_equal, &new_object); |
4443 | 4443 |
4444 // Allocate the JSObject on the heap. | 4444 // Allocate the JSObject on the heap. |
4445 Label allocate, done_allocate; | 4445 Label allocate, done_allocate; |
4446 __ movzxbl(rbx, FieldOperand(rcx, Map::kInstanceSizeOffset)); | 4446 __ movzxbl(rbx, FieldOperand(rcx, Map::kInstanceSizeOffset)); |
4447 __ leal(rbx, Operand(rbx, times_pointer_size, 0)); | 4447 __ leal(rbx, Operand(rbx, times_pointer_size, 0)); |
4448 __ Allocate(rbx, rax, rdi, no_reg, &allocate, NO_ALLOCATION_FLAGS); | 4448 __ Allocate(rbx, rax, rdi, no_reg, &allocate, NO_ALLOCATION_FLAGS); |
4449 __ bind(&done_allocate); | 4449 __ bind(&done_allocate); |
4450 | 4450 |
4451 // Initialize the JSObject fields. | 4451 // Initialize the JSObject fields. |
4452 __ movp(Operand(rax, JSObject::kMapOffset), rcx); | 4452 __ movp(FieldOperand(rax, JSObject::kMapOffset), rcx); |
4453 __ LoadRoot(rbx, Heap::kEmptyFixedArrayRootIndex); | 4453 __ LoadRoot(rbx, Heap::kEmptyFixedArrayRootIndex); |
4454 __ movp(Operand(rax, JSObject::kPropertiesOffset), rbx); | 4454 __ movp(FieldOperand(rax, JSObject::kPropertiesOffset), rbx); |
4455 __ movp(Operand(rax, JSObject::kElementsOffset), rbx); | 4455 __ movp(FieldOperand(rax, JSObject::kElementsOffset), rbx); |
4456 STATIC_ASSERT(JSObject::kHeaderSize == 3 * kPointerSize); | 4456 STATIC_ASSERT(JSObject::kHeaderSize == 3 * kPointerSize); |
4457 __ leap(rbx, Operand(rax, JSObject::kHeaderSize)); | 4457 __ leap(rbx, FieldOperand(rax, JSObject::kHeaderSize)); |
4458 | 4458 |
4459 // ----------- S t a t e ------------- | 4459 // ----------- S t a t e ------------- |
4460 // -- rax : result (untagged) | 4460 // -- rax : result (tagged) |
4461 // -- rbx : result fields (untagged) | 4461 // -- rbx : result fields (untagged) |
4462 // -- rdi : result end (untagged) | 4462 // -- rdi : result end (untagged) |
4463 // -- rcx : initial map | 4463 // -- rcx : initial map |
4464 // -- rsi : context | 4464 // -- rsi : context |
4465 // -- rsp[0] : return address | 4465 // -- rsp[0] : return address |
4466 // ----------------------------------- | 4466 // ----------------------------------- |
4467 | 4467 |
4468 // Perform in-object slack tracking if requested. | 4468 // Perform in-object slack tracking if requested. |
4469 Label slack_tracking; | 4469 Label slack_tracking; |
4470 STATIC_ASSERT(Map::kNoSlackTracking == 0); | 4470 STATIC_ASSERT(Map::kNoSlackTracking == 0); |
4471 __ LoadRoot(r11, Heap::kUndefinedValueRootIndex); | 4471 __ LoadRoot(r11, Heap::kUndefinedValueRootIndex); |
4472 __ testl(FieldOperand(rcx, Map::kBitField3Offset), | 4472 __ testl(FieldOperand(rcx, Map::kBitField3Offset), |
4473 Immediate(Map::ConstructionCounter::kMask)); | 4473 Immediate(Map::ConstructionCounter::kMask)); |
4474 __ j(not_zero, &slack_tracking, Label::kNear); | 4474 __ j(not_zero, &slack_tracking, Label::kNear); |
4475 { | 4475 { |
4476 // Initialize all in-object fields with undefined. | 4476 // Initialize all in-object fields with undefined. |
4477 __ InitializeFieldsWithFiller(rbx, rdi, r11); | 4477 __ InitializeFieldsWithFiller(rbx, rdi, r11); |
4478 | |
4479 // Add the object tag to make the JSObject real. | |
4480 STATIC_ASSERT(kHeapObjectTag == 1); | |
4481 __ incp(rax); | |
4482 __ Ret(); | 4478 __ Ret(); |
4483 } | 4479 } |
4484 __ bind(&slack_tracking); | 4480 __ bind(&slack_tracking); |
4485 { | 4481 { |
4486 // Decrease generous allocation count. | 4482 // Decrease generous allocation count. |
4487 STATIC_ASSERT(Map::ConstructionCounter::kNext == 32); | 4483 STATIC_ASSERT(Map::ConstructionCounter::kNext == 32); |
4488 __ subl(FieldOperand(rcx, Map::kBitField3Offset), | 4484 __ subl(FieldOperand(rcx, Map::kBitField3Offset), |
4489 Immediate(1 << Map::ConstructionCounter::kShift)); | 4485 Immediate(1 << Map::ConstructionCounter::kShift)); |
4490 | 4486 |
4491 // Initialize the in-object fields with undefined. | 4487 // Initialize the in-object fields with undefined. |
4492 __ movzxbl(rdx, FieldOperand(rcx, Map::kUnusedPropertyFieldsOffset)); | 4488 __ movzxbl(rdx, FieldOperand(rcx, Map::kUnusedPropertyFieldsOffset)); |
4493 __ negp(rdx); | 4489 __ negp(rdx); |
4494 __ leap(rdx, Operand(rdi, rdx, times_pointer_size, 0)); | 4490 __ leap(rdx, Operand(rdi, rdx, times_pointer_size, 0)); |
4495 __ InitializeFieldsWithFiller(rbx, rdx, r11); | 4491 __ InitializeFieldsWithFiller(rbx, rdx, r11); |
4496 | 4492 |
4497 // Initialize the remaining (reserved) fields with one pointer filler map. | 4493 // Initialize the remaining (reserved) fields with one pointer filler map. |
4498 __ LoadRoot(r11, Heap::kOnePointerFillerMapRootIndex); | 4494 __ LoadRoot(r11, Heap::kOnePointerFillerMapRootIndex); |
4499 __ InitializeFieldsWithFiller(rdx, rdi, r11); | 4495 __ InitializeFieldsWithFiller(rdx, rdi, r11); |
4500 | 4496 |
4501 // Add the object tag to make the JSObject real. | |
4502 STATIC_ASSERT(kHeapObjectTag == 1); | |
4503 __ incp(rax); | |
4504 | |
4505 // Check if we can finalize the instance size. | 4497 // Check if we can finalize the instance size. |
4506 Label finalize; | 4498 Label finalize; |
4507 STATIC_ASSERT(Map::kSlackTrackingCounterEnd == 1); | 4499 STATIC_ASSERT(Map::kSlackTrackingCounterEnd == 1); |
4508 __ testl(FieldOperand(rcx, Map::kBitField3Offset), | 4500 __ testl(FieldOperand(rcx, Map::kBitField3Offset), |
4509 Immediate(Map::ConstructionCounter::kMask)); | 4501 Immediate(Map::ConstructionCounter::kMask)); |
4510 __ j(zero, &finalize, Label::kNear); | 4502 __ j(zero, &finalize, Label::kNear); |
4511 __ Ret(); | 4503 __ Ret(); |
4512 | 4504 |
4513 // Finalize the instance size. | 4505 // Finalize the instance size. |
4514 __ bind(&finalize); | 4506 __ bind(&finalize); |
(...skipping 10 matching lines...) Expand all Loading... |
4525 // Fall back to %AllocateInNewSpace. | 4517 // Fall back to %AllocateInNewSpace. |
4526 __ bind(&allocate); | 4518 __ bind(&allocate); |
4527 { | 4519 { |
4528 FrameScope scope(masm, StackFrame::INTERNAL); | 4520 FrameScope scope(masm, StackFrame::INTERNAL); |
4529 __ Integer32ToSmi(rbx, rbx); | 4521 __ Integer32ToSmi(rbx, rbx); |
4530 __ Push(rcx); | 4522 __ Push(rcx); |
4531 __ Push(rbx); | 4523 __ Push(rbx); |
4532 __ CallRuntime(Runtime::kAllocateInNewSpace); | 4524 __ CallRuntime(Runtime::kAllocateInNewSpace); |
4533 __ Pop(rcx); | 4525 __ Pop(rcx); |
4534 } | 4526 } |
4535 STATIC_ASSERT(kHeapObjectTag == 1); | |
4536 __ decp(rax); | |
4537 __ movzxbl(rbx, FieldOperand(rcx, Map::kInstanceSizeOffset)); | 4527 __ movzxbl(rbx, FieldOperand(rcx, Map::kInstanceSizeOffset)); |
4538 __ leap(rdi, Operand(rax, rbx, times_pointer_size, 0)); | 4528 __ leap(rdi, Operand(rax, rbx, times_pointer_size, 0)); |
| 4529 STATIC_ASSERT(kHeapObjectTag == 1); |
| 4530 __ decp(rdi); // Remove the tag from the end address. |
4539 __ jmp(&done_allocate); | 4531 __ jmp(&done_allocate); |
4540 | 4532 |
4541 // Fall back to %NewObject. | 4533 // Fall back to %NewObject. |
4542 __ bind(&new_object); | 4534 __ bind(&new_object); |
4543 __ PopReturnAddressTo(rcx); | 4535 __ PopReturnAddressTo(rcx); |
4544 __ Push(rdi); | 4536 __ Push(rdi); |
4545 __ Push(rdx); | 4537 __ Push(rdx); |
4546 __ PushReturnAddressFrom(rcx); | 4538 __ PushReturnAddressFrom(rcx); |
4547 __ TailCallRuntime(Runtime::kNewObject); | 4539 __ TailCallRuntime(Runtime::kNewObject); |
4548 } | 4540 } |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4594 // Return an empty rest parameter array. | 4586 // Return an empty rest parameter array. |
4595 __ bind(&no_rest_parameters); | 4587 __ bind(&no_rest_parameters); |
4596 { | 4588 { |
4597 // ----------- S t a t e ------------- | 4589 // ----------- S t a t e ------------- |
4598 // -- rsi : context | 4590 // -- rsi : context |
4599 // -- rsp[0] : return address | 4591 // -- rsp[0] : return address |
4600 // ----------------------------------- | 4592 // ----------------------------------- |
4601 | 4593 |
4602 // Allocate an empty rest parameter array. | 4594 // Allocate an empty rest parameter array. |
4603 Label allocate, done_allocate; | 4595 Label allocate, done_allocate; |
4604 __ Allocate(JSArray::kSize, rax, rdx, rcx, &allocate, TAG_OBJECT); | 4596 __ Allocate(JSArray::kSize, rax, rdx, rcx, &allocate, NO_ALLOCATION_FLAGS); |
4605 __ bind(&done_allocate); | 4597 __ bind(&done_allocate); |
4606 | 4598 |
4607 // Setup the rest parameter array in rax. | 4599 // Setup the rest parameter array in rax. |
4608 __ LoadNativeContextSlot(Context::JS_ARRAY_FAST_ELEMENTS_MAP_INDEX, rcx); | 4600 __ LoadNativeContextSlot(Context::JS_ARRAY_FAST_ELEMENTS_MAP_INDEX, rcx); |
4609 __ movp(FieldOperand(rax, JSArray::kMapOffset), rcx); | 4601 __ movp(FieldOperand(rax, JSArray::kMapOffset), rcx); |
4610 __ LoadRoot(rcx, Heap::kEmptyFixedArrayRootIndex); | 4602 __ LoadRoot(rcx, Heap::kEmptyFixedArrayRootIndex); |
4611 __ movp(FieldOperand(rax, JSArray::kPropertiesOffset), rcx); | 4603 __ movp(FieldOperand(rax, JSArray::kPropertiesOffset), rcx); |
4612 __ movp(FieldOperand(rax, JSArray::kElementsOffset), rcx); | 4604 __ movp(FieldOperand(rax, JSArray::kElementsOffset), rcx); |
4613 __ movp(FieldOperand(rax, JSArray::kLengthOffset), Immediate(0)); | 4605 __ movp(FieldOperand(rax, JSArray::kLengthOffset), Immediate(0)); |
4614 STATIC_ASSERT(JSArray::kSize == 4 * kPointerSize); | 4606 STATIC_ASSERT(JSArray::kSize == 4 * kPointerSize); |
(...skipping 20 matching lines...) Expand all Loading... |
4635 // -- rsi : context | 4627 // -- rsi : context |
4636 // -- rax : number of rest parameters | 4628 // -- rax : number of rest parameters |
4637 // -- rbx : pointer to first rest parameters | 4629 // -- rbx : pointer to first rest parameters |
4638 // -- rsp[0] : return address | 4630 // -- rsp[0] : return address |
4639 // ----------------------------------- | 4631 // ----------------------------------- |
4640 | 4632 |
4641 // Allocate space for the rest parameter array plus the backing store. | 4633 // Allocate space for the rest parameter array plus the backing store. |
4642 Label allocate, done_allocate; | 4634 Label allocate, done_allocate; |
4643 __ leal(rcx, Operand(rax, times_pointer_size, | 4635 __ leal(rcx, Operand(rax, times_pointer_size, |
4644 JSArray::kSize + FixedArray::kHeaderSize)); | 4636 JSArray::kSize + FixedArray::kHeaderSize)); |
4645 __ Allocate(rcx, rdx, rdi, no_reg, &allocate, TAG_OBJECT); | 4637 __ Allocate(rcx, rdx, rdi, no_reg, &allocate, NO_ALLOCATION_FLAGS); |
4646 __ bind(&done_allocate); | 4638 __ bind(&done_allocate); |
4647 | 4639 |
4648 // Compute the arguments.length in rdi. | 4640 // Compute the arguments.length in rdi. |
4649 __ Integer32ToSmi(rdi, rax); | 4641 __ Integer32ToSmi(rdi, rax); |
4650 | 4642 |
4651 // Setup the elements array in rdx. | 4643 // Setup the elements array in rdx. |
4652 __ LoadRoot(rcx, Heap::kFixedArrayMapRootIndex); | 4644 __ LoadRoot(rcx, Heap::kFixedArrayMapRootIndex); |
4653 __ movp(FieldOperand(rdx, FixedArray::kMapOffset), rcx); | 4645 __ movp(FieldOperand(rdx, FixedArray::kMapOffset), rcx); |
4654 __ movp(FieldOperand(rdx, FixedArray::kLengthOffset), rdi); | 4646 __ movp(FieldOperand(rdx, FixedArray::kLengthOffset), rdi); |
4655 { | 4647 { |
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4783 __ leap(r8, Operand(rbx, times_pointer_size, kParameterMapHeaderSize)); | 4775 __ leap(r8, Operand(rbx, times_pointer_size, kParameterMapHeaderSize)); |
4784 __ bind(&no_parameter_map); | 4776 __ bind(&no_parameter_map); |
4785 | 4777 |
4786 // 2. Backing store. | 4778 // 2. Backing store. |
4787 __ leap(r8, Operand(r8, r11, times_pointer_size, FixedArray::kHeaderSize)); | 4779 __ leap(r8, Operand(r8, r11, times_pointer_size, FixedArray::kHeaderSize)); |
4788 | 4780 |
4789 // 3. Arguments object. | 4781 // 3. Arguments object. |
4790 __ addp(r8, Immediate(JSSloppyArgumentsObject::kSize)); | 4782 __ addp(r8, Immediate(JSSloppyArgumentsObject::kSize)); |
4791 | 4783 |
4792 // Do the allocation of all three objects in one go. | 4784 // Do the allocation of all three objects in one go. |
4793 __ Allocate(r8, rax, r9, no_reg, &runtime, TAG_OBJECT); | 4785 __ Allocate(r8, rax, r9, no_reg, &runtime, NO_ALLOCATION_FLAGS); |
4794 | 4786 |
4795 // rax = address of new object(s) (tagged) | 4787 // rax = address of new object(s) (tagged) |
4796 // r11 = argument count (untagged) | 4788 // r11 = argument count (untagged) |
4797 // Get the arguments map from the current native context into r9. | 4789 // Get the arguments map from the current native context into r9. |
4798 Label has_mapped_parameters, instantiate; | 4790 Label has_mapped_parameters, instantiate; |
4799 __ movp(r9, NativeContextOperand()); | 4791 __ movp(r9, NativeContextOperand()); |
4800 __ testp(rbx, rbx); | 4792 __ testp(rbx, rbx); |
4801 __ j(not_zero, &has_mapped_parameters, Label::kNear); | 4793 __ j(not_zero, &has_mapped_parameters, Label::kNear); |
4802 | 4794 |
4803 const int kIndex = Context::SLOPPY_ARGUMENTS_MAP_INDEX; | 4795 const int kIndex = Context::SLOPPY_ARGUMENTS_MAP_INDEX; |
(...skipping 183 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4987 // -- rax : number of arguments | 4979 // -- rax : number of arguments |
4988 // -- rbx : pointer to the first argument | 4980 // -- rbx : pointer to the first argument |
4989 // -- rsi : context | 4981 // -- rsi : context |
4990 // -- rsp[0] : return address | 4982 // -- rsp[0] : return address |
4991 // ----------------------------------- | 4983 // ----------------------------------- |
4992 | 4984 |
4993 // Allocate space for the strict arguments object plus the backing store. | 4985 // Allocate space for the strict arguments object plus the backing store. |
4994 Label allocate, done_allocate; | 4986 Label allocate, done_allocate; |
4995 __ leal(rcx, Operand(rax, times_pointer_size, JSStrictArgumentsObject::kSize + | 4987 __ leal(rcx, Operand(rax, times_pointer_size, JSStrictArgumentsObject::kSize + |
4996 FixedArray::kHeaderSize)); | 4988 FixedArray::kHeaderSize)); |
4997 __ Allocate(rcx, rdx, rdi, no_reg, &allocate, TAG_OBJECT); | 4989 __ Allocate(rcx, rdx, rdi, no_reg, &allocate, NO_ALLOCATION_FLAGS); |
4998 __ bind(&done_allocate); | 4990 __ bind(&done_allocate); |
4999 | 4991 |
5000 // Compute the arguments.length in rdi. | 4992 // Compute the arguments.length in rdi. |
5001 __ Integer32ToSmi(rdi, rax); | 4993 __ Integer32ToSmi(rdi, rax); |
5002 | 4994 |
5003 // Setup the elements array in rdx. | 4995 // Setup the elements array in rdx. |
5004 __ LoadRoot(rcx, Heap::kFixedArrayMapRootIndex); | 4996 __ LoadRoot(rcx, Heap::kFixedArrayMapRootIndex); |
5005 __ movp(FieldOperand(rdx, FixedArray::kMapOffset), rcx); | 4997 __ movp(FieldOperand(rdx, FixedArray::kMapOffset), rcx); |
5006 __ movp(FieldOperand(rdx, FixedArray::kLengthOffset), rdi); | 4998 __ movp(FieldOperand(rdx, FixedArray::kLengthOffset), rdi); |
5007 { | 4999 { |
(...skipping 579 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5587 kStackUnwindSpace, nullptr, return_value_operand, | 5579 kStackUnwindSpace, nullptr, return_value_operand, |
5588 NULL); | 5580 NULL); |
5589 } | 5581 } |
5590 | 5582 |
5591 #undef __ | 5583 #undef __ |
5592 | 5584 |
5593 } // namespace internal | 5585 } // namespace internal |
5594 } // namespace v8 | 5586 } // namespace v8 |
5595 | 5587 |
5596 #endif // V8_TARGET_ARCH_X64 | 5588 #endif // V8_TARGET_ARCH_X64 |
OLD | NEW |