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/bootstrapper.h" | 7 #include "src/bootstrapper.h" |
8 #include "src/code-stubs.h" | 8 #include "src/code-stubs.h" |
9 #include "src/codegen.h" | 9 #include "src/codegen.h" |
10 #include "src/ic/handler-compiler.h" | 10 #include "src/ic/handler-compiler.h" |
(...skipping 4446 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4457 Label fast_elements_case; | 4457 Label fast_elements_case; |
4458 __ cmpl(rcx, Immediate(FAST_ELEMENTS)); | 4458 __ cmpl(rcx, Immediate(FAST_ELEMENTS)); |
4459 __ j(equal, &fast_elements_case); | 4459 __ j(equal, &fast_elements_case); |
4460 GenerateCase(masm, FAST_HOLEY_ELEMENTS); | 4460 GenerateCase(masm, FAST_HOLEY_ELEMENTS); |
4461 | 4461 |
4462 __ bind(&fast_elements_case); | 4462 __ bind(&fast_elements_case); |
4463 GenerateCase(masm, FAST_ELEMENTS); | 4463 GenerateCase(masm, FAST_ELEMENTS); |
4464 } | 4464 } |
4465 | 4465 |
4466 | 4466 |
| 4467 void FastNewObjectStub::Generate(MacroAssembler* masm) { |
| 4468 // ----------- S t a t e ------------- |
| 4469 // -- rdi : target |
| 4470 // -- rdx : new target |
| 4471 // -- rsi : context |
| 4472 // -- rsp[0] : return address |
| 4473 // ----------------------------------- |
| 4474 __ AssertFunction(rdi); |
| 4475 __ AssertReceiver(rdx); |
| 4476 |
| 4477 // Verify that the new target is a JSFunction. |
| 4478 Label new_object; |
| 4479 __ CmpObjectType(rdx, JS_FUNCTION_TYPE, rbx); |
| 4480 __ j(not_equal, &new_object); |
| 4481 |
| 4482 // Load the initial map and verify that it's in fact a map. |
| 4483 __ movp(rcx, FieldOperand(rdx, JSFunction::kPrototypeOrInitialMapOffset)); |
| 4484 __ JumpIfSmi(rcx, &new_object); |
| 4485 __ CmpObjectType(rcx, MAP_TYPE, rbx); |
| 4486 __ j(not_equal, &new_object); |
| 4487 |
| 4488 // Fall back to runtime if the target differs from the new target's |
| 4489 // initial map constructor. |
| 4490 __ cmpp(rdi, FieldOperand(rcx, Map::kConstructorOrBackPointerOffset)); |
| 4491 __ j(not_equal, &new_object); |
| 4492 |
| 4493 // Allocate the JSObject on the heap. |
| 4494 Label allocate, done_allocate; |
| 4495 __ movzxbl(rbx, FieldOperand(rcx, Map::kInstanceSizeOffset)); |
| 4496 __ leal(rbx, Operand(rbx, times_pointer_size, 0)); |
| 4497 __ Allocate(rbx, rax, rdi, no_reg, &allocate, NO_ALLOCATION_FLAGS); |
| 4498 __ bind(&done_allocate); |
| 4499 |
| 4500 // Initialize the JSObject fields. |
| 4501 __ movp(Operand(rax, JSObject::kMapOffset), rcx); |
| 4502 __ LoadRoot(rbx, Heap::kEmptyFixedArrayRootIndex); |
| 4503 __ movp(Operand(rax, JSObject::kPropertiesOffset), rbx); |
| 4504 __ movp(Operand(rax, JSObject::kElementsOffset), rbx); |
| 4505 STATIC_ASSERT(JSObject::kHeaderSize == 3 * kPointerSize); |
| 4506 __ leap(rbx, Operand(rax, JSObject::kHeaderSize)); |
| 4507 |
| 4508 // ----------- S t a t e ------------- |
| 4509 // -- rax : result (untagged) |
| 4510 // -- rbx : result fields (untagged) |
| 4511 // -- rdi : result end (untagged) |
| 4512 // -- rcx : initial map |
| 4513 // -- rsi : context |
| 4514 // -- rsp[0] : return address |
| 4515 // ----------------------------------- |
| 4516 |
| 4517 // Perform in-object slack tracking if requested. |
| 4518 Label slack_tracking; |
| 4519 STATIC_ASSERT(Map::kNoSlackTracking == 0); |
| 4520 __ LoadRoot(r11, Heap::kUndefinedValueRootIndex); |
| 4521 __ testl(FieldOperand(rcx, Map::kBitField3Offset), |
| 4522 Immediate(Map::ConstructionCounter::kMask)); |
| 4523 __ j(not_zero, &slack_tracking, Label::kNear); |
| 4524 { |
| 4525 // Initialize all in-object fields with undefined. |
| 4526 __ InitializeFieldsWithFiller(rbx, rdi, r11); |
| 4527 |
| 4528 // Add the object tag to make the JSObject real. |
| 4529 STATIC_ASSERT(kHeapObjectTag == 1); |
| 4530 __ incp(rax); |
| 4531 __ Ret(); |
| 4532 } |
| 4533 __ bind(&slack_tracking); |
| 4534 { |
| 4535 // Decrease generous allocation count. |
| 4536 STATIC_ASSERT(Map::ConstructionCounter::kNext == 32); |
| 4537 __ subl(FieldOperand(rcx, Map::kBitField3Offset), |
| 4538 Immediate(1 << Map::ConstructionCounter::kShift)); |
| 4539 |
| 4540 // Initialize the in-object fields with undefined. |
| 4541 __ movzxbl(rdx, FieldOperand(rcx, Map::kUnusedPropertyFieldsOffset)); |
| 4542 __ negp(rdx); |
| 4543 __ leap(rdx, Operand(rdi, rdx, times_pointer_size, 0)); |
| 4544 __ InitializeFieldsWithFiller(rbx, rdx, r11); |
| 4545 |
| 4546 // Initialize the remaining (reserved) fields with one pointer filler map. |
| 4547 __ LoadRoot(r11, Heap::kOnePointerFillerMapRootIndex); |
| 4548 __ InitializeFieldsWithFiller(rdx, rdi, r11); |
| 4549 |
| 4550 // Add the object tag to make the JSObject real. |
| 4551 STATIC_ASSERT(kHeapObjectTag == 1); |
| 4552 __ incp(rax); |
| 4553 |
| 4554 // Check if we can finalize the instance size. |
| 4555 Label finalize; |
| 4556 STATIC_ASSERT(Map::kSlackTrackingCounterEnd == 1); |
| 4557 __ testl(FieldOperand(rcx, Map::kBitField3Offset), |
| 4558 Immediate(Map::ConstructionCounter::kMask)); |
| 4559 __ j(zero, &finalize, Label::kNear); |
| 4560 __ Ret(); |
| 4561 |
| 4562 // Finalize the instance size. |
| 4563 __ bind(&finalize); |
| 4564 { |
| 4565 FrameScope scope(masm, StackFrame::INTERNAL); |
| 4566 __ Push(rax); |
| 4567 __ Push(rcx); |
| 4568 __ CallRuntime(Runtime::kFinalizeInstanceSize); |
| 4569 __ Pop(rax); |
| 4570 } |
| 4571 __ Ret(); |
| 4572 } |
| 4573 |
| 4574 // Fall back to %AllocateInNewSpace. |
| 4575 __ bind(&allocate); |
| 4576 { |
| 4577 FrameScope scope(masm, StackFrame::INTERNAL); |
| 4578 __ Integer32ToSmi(rbx, rbx); |
| 4579 __ Push(rcx); |
| 4580 __ Push(rbx); |
| 4581 __ CallRuntime(Runtime::kAllocateInNewSpace); |
| 4582 __ Pop(rcx); |
| 4583 } |
| 4584 STATIC_ASSERT(kHeapObjectTag == 1); |
| 4585 __ decp(rax); |
| 4586 __ movzxbl(rbx, FieldOperand(rcx, Map::kInstanceSizeOffset)); |
| 4587 __ leap(rdi, Operand(rax, rbx, times_pointer_size, 0)); |
| 4588 __ jmp(&done_allocate); |
| 4589 |
| 4590 // Fall back to %NewObject. |
| 4591 __ bind(&new_object); |
| 4592 __ PopReturnAddressTo(rcx); |
| 4593 __ Push(rdi); |
| 4594 __ Push(rdx); |
| 4595 __ PushReturnAddressFrom(rcx); |
| 4596 __ TailCallRuntime(Runtime::kNewObject); |
| 4597 } |
| 4598 |
| 4599 |
4467 void FastNewRestParameterStub::Generate(MacroAssembler* masm) { | 4600 void FastNewRestParameterStub::Generate(MacroAssembler* masm) { |
4468 // ----------- S t a t e ------------- | 4601 // ----------- S t a t e ------------- |
4469 // -- rdi : function | 4602 // -- rdi : function |
4470 // -- rsi : context | 4603 // -- rsi : context |
4471 // -- rbp : frame pointer | 4604 // -- rbp : frame pointer |
4472 // -- rsp[0] : return address | 4605 // -- rsp[0] : return address |
4473 // ----------------------------------- | 4606 // ----------------------------------- |
4474 __ AssertFunction(rdi); | 4607 __ AssertFunction(rdi); |
4475 | 4608 |
4476 // For Ignition we need to skip all possible handler/stub frames until | 4609 // For Ignition we need to skip all possible handler/stub frames until |
(...skipping 1026 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5503 NULL); | 5636 NULL); |
5504 } | 5637 } |
5505 | 5638 |
5506 | 5639 |
5507 #undef __ | 5640 #undef __ |
5508 | 5641 |
5509 } // namespace internal | 5642 } // namespace internal |
5510 } // namespace v8 | 5643 } // namespace v8 |
5511 | 5644 |
5512 #endif // V8_TARGET_ARCH_X64 | 5645 #endif // V8_TARGET_ARCH_X64 |
OLD | NEW |