| 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 |