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 #include "src/v8.h" | 5 #include "src/v8.h" |
6 | 6 |
7 #if V8_TARGET_ARCH_X87 | 7 #if V8_TARGET_ARCH_X87 |
8 | 8 |
9 #include "src/base/bits.h" | 9 #include "src/base/bits.h" |
10 #include "src/bootstrapper.h" | 10 #include "src/bootstrapper.h" |
(...skipping 401 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
412 StubRuntimeCallHelper call_helper; | 412 StubRuntimeCallHelper call_helper; |
413 char_at_generator.GenerateSlow(masm, call_helper); | 413 char_at_generator.GenerateSlow(masm, call_helper); |
414 | 414 |
415 __ bind(&miss); | 415 __ bind(&miss); |
416 PropertyAccessCompiler::TailCallBuiltin( | 416 PropertyAccessCompiler::TailCallBuiltin( |
417 masm, PropertyAccessCompiler::MissBuiltin(Code::KEYED_LOAD_IC)); | 417 masm, PropertyAccessCompiler::MissBuiltin(Code::KEYED_LOAD_IC)); |
418 } | 418 } |
419 | 419 |
420 | 420 |
421 void ArgumentsAccessStub::GenerateReadElement(MacroAssembler* masm) { | 421 void ArgumentsAccessStub::GenerateReadElement(MacroAssembler* masm) { |
| 422 CHECK(!has_new_target()); |
422 // The key is in edx and the parameter count is in eax. | 423 // The key is in edx and the parameter count is in eax. |
423 DCHECK(edx.is(ArgumentsAccessReadDescriptor::index())); | 424 DCHECK(edx.is(ArgumentsAccessReadDescriptor::index())); |
424 DCHECK(eax.is(ArgumentsAccessReadDescriptor::parameter_count())); | 425 DCHECK(eax.is(ArgumentsAccessReadDescriptor::parameter_count())); |
425 | 426 |
426 // The displacement is used for skipping the frame pointer on the | 427 // The displacement is used for skipping the frame pointer on the |
427 // stack. It is the offset of the last parameter (if any) relative | 428 // stack. It is the offset of the last parameter (if any) relative |
428 // to the frame pointer. | 429 // to the frame pointer. |
429 static const int kDisplacement = 1 * kPointerSize; | 430 static const int kDisplacement = 1 * kPointerSize; |
430 | 431 |
431 // Check that the key is a smi. | 432 // Check that the key is a smi. |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
478 __ TailCallRuntime(Runtime::kGetArgumentsProperty, 1, 1); | 479 __ TailCallRuntime(Runtime::kGetArgumentsProperty, 1, 1); |
479 } | 480 } |
480 | 481 |
481 | 482 |
482 void ArgumentsAccessStub::GenerateNewSloppySlow(MacroAssembler* masm) { | 483 void ArgumentsAccessStub::GenerateNewSloppySlow(MacroAssembler* masm) { |
483 // esp[0] : return address | 484 // esp[0] : return address |
484 // esp[4] : number of parameters | 485 // esp[4] : number of parameters |
485 // esp[8] : receiver displacement | 486 // esp[8] : receiver displacement |
486 // esp[12] : function | 487 // esp[12] : function |
487 | 488 |
| 489 CHECK(!has_new_target()); |
| 490 |
488 // Check if the calling frame is an arguments adaptor frame. | 491 // Check if the calling frame is an arguments adaptor frame. |
489 Label runtime; | 492 Label runtime; |
490 __ mov(edx, Operand(ebp, StandardFrameConstants::kCallerFPOffset)); | 493 __ mov(edx, Operand(ebp, StandardFrameConstants::kCallerFPOffset)); |
491 __ mov(ecx, Operand(edx, StandardFrameConstants::kContextOffset)); | 494 __ mov(ecx, Operand(edx, StandardFrameConstants::kContextOffset)); |
492 __ cmp(ecx, Immediate(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR))); | 495 __ cmp(ecx, Immediate(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR))); |
493 __ j(not_equal, &runtime, Label::kNear); | 496 __ j(not_equal, &runtime, Label::kNear); |
494 | 497 |
495 // Patch the arguments.length and the parameters pointer. | 498 // Patch the arguments.length and the parameters pointer. |
496 __ mov(ecx, Operand(edx, ArgumentsAdaptorFrameConstants::kLengthOffset)); | 499 __ mov(ecx, Operand(edx, ArgumentsAdaptorFrameConstants::kLengthOffset)); |
497 __ mov(Operand(esp, 1 * kPointerSize), ecx); | 500 __ mov(Operand(esp, 1 * kPointerSize), ecx); |
498 __ lea(edx, Operand(edx, ecx, times_2, | 501 __ lea(edx, Operand(edx, ecx, times_2, |
499 StandardFrameConstants::kCallerSPOffset)); | 502 StandardFrameConstants::kCallerSPOffset)); |
500 __ mov(Operand(esp, 2 * kPointerSize), edx); | 503 __ mov(Operand(esp, 2 * kPointerSize), edx); |
501 | 504 |
502 __ bind(&runtime); | 505 __ bind(&runtime); |
503 __ TailCallRuntime(Runtime::kNewSloppyArguments, 3, 1); | 506 __ TailCallRuntime(Runtime::kNewSloppyArguments, 3, 1); |
504 } | 507 } |
505 | 508 |
506 | 509 |
507 void ArgumentsAccessStub::GenerateNewSloppyFast(MacroAssembler* masm) { | 510 void ArgumentsAccessStub::GenerateNewSloppyFast(MacroAssembler* masm) { |
508 // esp[0] : return address | 511 // esp[0] : return address |
509 // esp[4] : number of parameters (tagged) | 512 // esp[4] : number of parameters (tagged) |
510 // esp[8] : receiver displacement | 513 // esp[8] : receiver displacement |
511 // esp[12] : function | 514 // esp[12] : function |
512 | 515 |
513 // ebx = parameter count (tagged) | 516 // ebx = parameter count (tagged) |
514 __ mov(ebx, Operand(esp, 1 * kPointerSize)); | 517 __ mov(ebx, Operand(esp, 1 * kPointerSize)); |
515 | 518 |
| 519 CHECK(!has_new_target()); |
| 520 |
516 // Check if the calling frame is an arguments adaptor frame. | 521 // Check if the calling frame is an arguments adaptor frame. |
517 // TODO(rossberg): Factor out some of the bits that are shared with the other | 522 // TODO(rossberg): Factor out some of the bits that are shared with the other |
518 // Generate* functions. | 523 // Generate* functions. |
519 Label runtime; | 524 Label runtime; |
520 Label adaptor_frame, try_allocate; | 525 Label adaptor_frame, try_allocate; |
521 __ mov(edx, Operand(ebp, StandardFrameConstants::kCallerFPOffset)); | 526 __ mov(edx, Operand(ebp, StandardFrameConstants::kCallerFPOffset)); |
522 __ mov(ecx, Operand(edx, StandardFrameConstants::kContextOffset)); | 527 __ mov(ecx, Operand(edx, StandardFrameConstants::kContextOffset)); |
523 __ cmp(ecx, Immediate(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR))); | 528 __ cmp(ecx, Immediate(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR))); |
524 __ j(equal, &adaptor_frame, Label::kNear); | 529 __ j(equal, &adaptor_frame, Label::kNear); |
525 | 530 |
(...skipping 219 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
745 __ cmp(ecx, Immediate(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR))); | 750 __ cmp(ecx, Immediate(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR))); |
746 __ j(equal, &adaptor_frame, Label::kNear); | 751 __ j(equal, &adaptor_frame, Label::kNear); |
747 | 752 |
748 // Get the length from the frame. | 753 // Get the length from the frame. |
749 __ mov(ecx, Operand(esp, 1 * kPointerSize)); | 754 __ mov(ecx, Operand(esp, 1 * kPointerSize)); |
750 __ jmp(&try_allocate, Label::kNear); | 755 __ jmp(&try_allocate, Label::kNear); |
751 | 756 |
752 // Patch the arguments.length and the parameters pointer. | 757 // Patch the arguments.length and the parameters pointer. |
753 __ bind(&adaptor_frame); | 758 __ bind(&adaptor_frame); |
754 __ mov(ecx, Operand(edx, ArgumentsAdaptorFrameConstants::kLengthOffset)); | 759 __ mov(ecx, Operand(edx, ArgumentsAdaptorFrameConstants::kLengthOffset)); |
755 __ mov(Operand(esp, 1 * kPointerSize), ecx); | 760 |
| 761 if (has_new_target()) { |
| 762 // Subtract 1 from smi-tagged arguments count. |
| 763 __ sub(ecx, Immediate(2)); |
| 764 } |
| 765 |
756 __ lea(edx, Operand(edx, ecx, times_2, | 766 __ lea(edx, Operand(edx, ecx, times_2, |
757 StandardFrameConstants::kCallerSPOffset)); | 767 StandardFrameConstants::kCallerSPOffset)); |
| 768 __ mov(Operand(esp, 1 * kPointerSize), ecx); |
758 __ mov(Operand(esp, 2 * kPointerSize), edx); | 769 __ mov(Operand(esp, 2 * kPointerSize), edx); |
759 | 770 |
760 // Try the new space allocation. Start out with computing the size of | 771 // Try the new space allocation. Start out with computing the size of |
761 // the arguments object and the elements array. | 772 // the arguments object and the elements array. |
762 Label add_arguments_object; | 773 Label add_arguments_object; |
763 __ bind(&try_allocate); | 774 __ bind(&try_allocate); |
764 __ test(ecx, ecx); | 775 __ test(ecx, ecx); |
765 __ j(zero, &add_arguments_object, Label::kNear); | 776 __ j(zero, &add_arguments_object, Label::kNear); |
766 __ lea(ecx, Operand(ecx, times_2, FixedArray::kHeaderSize)); | 777 __ lea(ecx, Operand(ecx, times_2, FixedArray::kHeaderSize)); |
767 __ bind(&add_arguments_object); | 778 __ bind(&add_arguments_object); |
(...skipping 1061 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1829 isolate()->factory()->allocation_site_map(); | 1840 isolate()->factory()->allocation_site_map(); |
1830 __ cmp(FieldOperand(ebx, 0), Immediate(allocation_site_map)); | 1841 __ cmp(FieldOperand(ebx, 0), Immediate(allocation_site_map)); |
1831 __ j(equal, &feedback_register_initialized); | 1842 __ j(equal, &feedback_register_initialized); |
1832 __ mov(ebx, isolate()->factory()->undefined_value()); | 1843 __ mov(ebx, isolate()->factory()->undefined_value()); |
1833 __ bind(&feedback_register_initialized); | 1844 __ bind(&feedback_register_initialized); |
1834 } | 1845 } |
1835 | 1846 |
1836 __ AssertUndefinedOrAllocationSite(ebx); | 1847 __ AssertUndefinedOrAllocationSite(ebx); |
1837 } | 1848 } |
1838 | 1849 |
1839 // Pass original constructor to construct stub. | 1850 if (IsSuperConstructorCall()) { |
1840 __ mov(edx, edi); | 1851 __ mov(edx, Operand(esp, eax, times_pointer_size, 2 * kPointerSize)); |
| 1852 } else { |
| 1853 // Pass original constructor to construct stub. |
| 1854 __ mov(edx, edi); |
| 1855 } |
1841 | 1856 |
1842 // Jump to the function-specific construct stub. | 1857 // Jump to the function-specific construct stub. |
1843 Register jmp_reg = ecx; | 1858 Register jmp_reg = ecx; |
1844 __ mov(jmp_reg, FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset)); | 1859 __ mov(jmp_reg, FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset)); |
1845 __ mov(jmp_reg, FieldOperand(jmp_reg, | 1860 __ mov(jmp_reg, FieldOperand(jmp_reg, |
1846 SharedFunctionInfo::kConstructStubOffset)); | 1861 SharedFunctionInfo::kConstructStubOffset)); |
1847 __ lea(jmp_reg, FieldOperand(jmp_reg, Code::kHeaderSize)); | 1862 __ lea(jmp_reg, FieldOperand(jmp_reg, Code::kHeaderSize)); |
1848 __ jmp(jmp_reg); | 1863 __ jmp(jmp_reg); |
1849 | 1864 |
1850 // edi: called object | 1865 // edi: called object |
(...skipping 2907 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4758 ApiParameterOperand(2), kStackSpace, nullptr, | 4773 ApiParameterOperand(2), kStackSpace, nullptr, |
4759 Operand(ebp, 7 * kPointerSize), NULL); | 4774 Operand(ebp, 7 * kPointerSize), NULL); |
4760 } | 4775 } |
4761 | 4776 |
4762 | 4777 |
4763 #undef __ | 4778 #undef __ |
4764 | 4779 |
4765 } } // namespace v8::internal | 4780 } } // namespace v8::internal |
4766 | 4781 |
4767 #endif // V8_TARGET_ARCH_X87 | 4782 #endif // V8_TARGET_ARCH_X87 |
OLD | NEW |