Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(4)

Side by Side Diff: src/x64/lithium-codegen-x64.cc

Issue 145773008: A64: Synchronize with r17104. (Closed) Base URL: https://v8.googlecode.com/svn/branches/experimental/a64
Patch Set: Created 6 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/x64/lithium-codegen-x64.h ('k') | src/x64/lithium-x64.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2013 the V8 project authors. All rights reserved. 1 // Copyright 2013 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
82 GenerateDeferredCode() && 82 GenerateDeferredCode() &&
83 GenerateJumpTable() && 83 GenerateJumpTable() &&
84 GenerateSafepointTable(); 84 GenerateSafepointTable();
85 } 85 }
86 86
87 87
88 void LCodeGen::FinishCode(Handle<Code> code) { 88 void LCodeGen::FinishCode(Handle<Code> code) {
89 ASSERT(is_done()); 89 ASSERT(is_done());
90 code->set_stack_slots(GetStackSlotCount()); 90 code->set_stack_slots(GetStackSlotCount());
91 code->set_safepoint_table_offset(safepoints_.GetCodeOffset()); 91 code->set_safepoint_table_offset(safepoints_.GetCodeOffset());
92 if (FLAG_weak_embedded_maps_in_optimized_code) { 92 RegisterDependentCodeForEmbeddedMaps(code);
93 RegisterDependentCodeForEmbeddedMaps(code);
94 }
95 PopulateDeoptimizationData(code); 93 PopulateDeoptimizationData(code);
96 info()->CommitDependencies(code); 94 info()->CommitDependencies(code);
97 } 95 }
98 96
99 97
100 void LChunkBuilder::Abort(BailoutReason reason) { 98 void LChunkBuilder::Abort(BailoutReason reason) {
101 info()->set_bailout_reason(reason); 99 info()->set_bailout_reason(reason);
102 status_ = ABORTED; 100 status_ = ABORTED;
103 } 101 }
104 102
105 103
106 void LCodeGen::Comment(const char* format, ...) {
107 if (!FLAG_code_comments) return;
108 char buffer[4 * KB];
109 StringBuilder builder(buffer, ARRAY_SIZE(buffer));
110 va_list arguments;
111 va_start(arguments, format);
112 builder.AddFormattedList(format, arguments);
113 va_end(arguments);
114
115 // Copy the string before recording it in the assembler to avoid
116 // issues when the stack allocated buffer goes out of scope.
117 int length = builder.position();
118 Vector<char> copy = Vector<char>::New(length + 1);
119 OS::MemCopy(copy.start(), builder.Finalize(), copy.length());
120 masm()->RecordComment(copy.start());
121 }
122
123
124 #ifdef _MSC_VER 104 #ifdef _MSC_VER
125 void LCodeGen::MakeSureStackPagesMapped(int offset) { 105 void LCodeGen::MakeSureStackPagesMapped(int offset) {
126 const int kPageSize = 4 * KB; 106 const int kPageSize = 4 * KB;
127 for (offset -= kPageSize; offset > 0; offset -= kPageSize) { 107 for (offset -= kPageSize; offset > 0; offset -= kPageSize) {
128 __ movq(Operand(rsp, offset), rax); 108 __ movq(Operand(rsp, offset), rax);
129 } 109 }
130 } 110 }
131 #endif 111 #endif
132 112
133 113
(...skipping 11 matching lines...) Expand all
145 #endif 125 #endif
146 126
147 // Strict mode functions need to replace the receiver with undefined 127 // Strict mode functions need to replace the receiver with undefined
148 // when called as functions (without an explicit receiver 128 // when called as functions (without an explicit receiver
149 // object). rcx is zero for method calls and non-zero for function 129 // object). rcx is zero for method calls and non-zero for function
150 // calls. 130 // calls.
151 if (!info_->is_classic_mode() || info_->is_native()) { 131 if (!info_->is_classic_mode() || info_->is_native()) {
152 Label ok; 132 Label ok;
153 __ testq(rcx, rcx); 133 __ testq(rcx, rcx);
154 __ j(zero, &ok, Label::kNear); 134 __ j(zero, &ok, Label::kNear);
155 // +1 for return address. 135 StackArgumentsAccessor args(rsp, scope()->num_parameters());
156 int receiver_offset = (scope()->num_parameters() + 1) * kPointerSize;
157 __ LoadRoot(kScratchRegister, Heap::kUndefinedValueRootIndex); 136 __ LoadRoot(kScratchRegister, Heap::kUndefinedValueRootIndex);
158 __ movq(Operand(rsp, receiver_offset), kScratchRegister); 137 __ movq(args.GetReceiverOperand(), kScratchRegister);
159 __ bind(&ok); 138 __ bind(&ok);
160 } 139 }
161 } 140 }
162 141
163 info()->set_prologue_offset(masm_->pc_offset()); 142 info()->set_prologue_offset(masm_->pc_offset());
164 if (NeedsEagerFrame()) { 143 if (NeedsEagerFrame()) {
165 ASSERT(!frame_is_built_); 144 ASSERT(!frame_is_built_);
166 frame_is_built_ = true; 145 frame_is_built_ = true;
167 __ push(rbp); // Caller's frame pointer. 146 __ push(rbp); // Caller's frame pointer.
168 __ movq(rbp, rsp); 147 __ movq(rbp, rsp);
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after
266 osr_pc_offset_ = masm()->pc_offset(); 245 osr_pc_offset_ = masm()->pc_offset();
267 246
268 // Adjust the frame size, subsuming the unoptimized frame into the 247 // Adjust the frame size, subsuming the unoptimized frame into the
269 // optimized frame. 248 // optimized frame.
270 int slots = GetStackSlotCount() - graph()->osr()->UnoptimizedFrameSlots(); 249 int slots = GetStackSlotCount() - graph()->osr()->UnoptimizedFrameSlots();
271 ASSERT(slots >= 0); 250 ASSERT(slots >= 0);
272 __ subq(rsp, Immediate(slots * kPointerSize)); 251 __ subq(rsp, Immediate(slots * kPointerSize));
273 } 252 }
274 253
275 254
276 bool LCodeGen::GenerateBody() {
277 ASSERT(is_generating());
278 bool emit_instructions = true;
279 for (current_instruction_ = 0;
280 !is_aborted() && current_instruction_ < instructions_->length();
281 current_instruction_++) {
282 LInstruction* instr = instructions_->at(current_instruction_);
283
284 // Don't emit code for basic blocks with a replacement.
285 if (instr->IsLabel()) {
286 emit_instructions = !LLabel::cast(instr)->HasReplacement();
287 }
288 if (!emit_instructions) continue;
289
290 if (FLAG_code_comments && instr->HasInterestingComment(this)) {
291 Comment(";;; <@%d,#%d> %s",
292 current_instruction_,
293 instr->hydrogen_value()->id(),
294 instr->Mnemonic());
295 }
296
297 RecordAndUpdatePosition(instr->position());
298
299 instr->CompileToNative(this);
300 }
301 EnsureSpaceForLazyDeopt(Deoptimizer::patch_size());
302 return !is_aborted();
303 }
304
305
306 bool LCodeGen::GenerateJumpTable() { 255 bool LCodeGen::GenerateJumpTable() {
307 Label needs_frame; 256 Label needs_frame;
308 if (jump_table_.length() > 0) { 257 if (jump_table_.length() > 0) {
309 Comment(";;; -------------------- Jump table --------------------"); 258 Comment(";;; -------------------- Jump table --------------------");
310 } 259 }
311 for (int i = 0; i < jump_table_.length(); i++) { 260 for (int i = 0; i < jump_table_.length(); i++) {
312 __ bind(&jump_table_[i].label); 261 __ bind(&jump_table_[i].label);
313 Address entry = jump_table_[i].address; 262 Address entry = jump_table_[i].address;
314 Deoptimizer::BailoutType type = jump_table_[i].bailout_type; 263 Deoptimizer::BailoutType type = jump_table_[i].bailout_type;
315 int id = Deoptimizer::GetDeoptimizationId(isolate(), entry, type); 264 int id = Deoptimizer::GetDeoptimizationId(isolate(), entry, type);
(...skipping 314 matching lines...) Expand 10 before | Expand all | Expand 10 after
630 579
631 void LCodeGen::CallCode(Handle<Code> code, 580 void LCodeGen::CallCode(Handle<Code> code,
632 RelocInfo::Mode mode, 581 RelocInfo::Mode mode,
633 LInstruction* instr) { 582 LInstruction* instr) {
634 CallCodeGeneric(code, mode, instr, RECORD_SIMPLE_SAFEPOINT, 0); 583 CallCodeGeneric(code, mode, instr, RECORD_SIMPLE_SAFEPOINT, 0);
635 } 584 }
636 585
637 586
638 void LCodeGen::CallRuntime(const Runtime::Function* function, 587 void LCodeGen::CallRuntime(const Runtime::Function* function,
639 int num_arguments, 588 int num_arguments,
640 LInstruction* instr) { 589 LInstruction* instr,
590 SaveFPRegsMode save_doubles) {
641 ASSERT(instr != NULL); 591 ASSERT(instr != NULL);
642 ASSERT(instr->HasPointerMap()); 592 ASSERT(instr->HasPointerMap());
643 LPointerMap* pointers = instr->pointer_map(); 593 LPointerMap* pointers = instr->pointer_map();
644 RecordPosition(pointers->position()); 594 RecordPosition(pointers->position());
645 595
646 __ CallRuntime(function, num_arguments); 596 __ CallRuntime(function, num_arguments, save_doubles);
597
647 RecordSafepointWithLazyDeopt(instr, RECORD_SIMPLE_SAFEPOINT, 0); 598 RecordSafepointWithLazyDeopt(instr, RECORD_SIMPLE_SAFEPOINT, 0);
648 } 599 }
649 600
650 601
651 void LCodeGen::CallRuntimeFromDeferred(Runtime::FunctionId id, 602 void LCodeGen::CallRuntimeFromDeferred(Runtime::FunctionId id,
652 int argc, 603 int argc,
653 LInstruction* instr) { 604 LInstruction* instr) {
654 __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); 605 __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset));
655 __ CallRuntimeSaveDoubles(id); 606 __ CallRuntimeSaveDoubles(id);
656 RecordSafepointWithRegisters( 607 RecordSafepointWithRegisters(
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
747 LEnvironment* environment) { 698 LEnvironment* environment) {
748 Deoptimizer::BailoutType bailout_type = info()->IsStub() 699 Deoptimizer::BailoutType bailout_type = info()->IsStub()
749 ? Deoptimizer::LAZY 700 ? Deoptimizer::LAZY
750 : Deoptimizer::EAGER; 701 : Deoptimizer::EAGER;
751 DeoptimizeIf(cc, environment, bailout_type); 702 DeoptimizeIf(cc, environment, bailout_type);
752 } 703 }
753 704
754 705
755 void LCodeGen::RegisterDependentCodeForEmbeddedMaps(Handle<Code> code) { 706 void LCodeGen::RegisterDependentCodeForEmbeddedMaps(Handle<Code> code) {
756 ZoneList<Handle<Map> > maps(1, zone()); 707 ZoneList<Handle<Map> > maps(1, zone());
708 ZoneList<Handle<JSObject> > objects(1, zone());
757 int mode_mask = RelocInfo::ModeMask(RelocInfo::EMBEDDED_OBJECT); 709 int mode_mask = RelocInfo::ModeMask(RelocInfo::EMBEDDED_OBJECT);
758 for (RelocIterator it(*code, mode_mask); !it.done(); it.next()) { 710 for (RelocIterator it(*code, mode_mask); !it.done(); it.next()) {
759 RelocInfo::Mode mode = it.rinfo()->rmode(); 711 if (Code::IsWeakEmbeddedObject(code->kind(), it.rinfo()->target_object())) {
760 if (mode == RelocInfo::EMBEDDED_OBJECT && 712 if (it.rinfo()->target_object()->IsMap()) {
761 it.rinfo()->target_object()->IsMap()) { 713 Handle<Map> map(Map::cast(it.rinfo()->target_object()));
762 Handle<Map> map(Map::cast(it.rinfo()->target_object()));
763 if (map->CanTransition()) {
764 maps.Add(map, zone()); 714 maps.Add(map, zone());
715 } else if (it.rinfo()->target_object()->IsJSObject()) {
716 Handle<JSObject> object(JSObject::cast(it.rinfo()->target_object()));
717 objects.Add(object, zone());
765 } 718 }
766 } 719 }
767 } 720 }
768 #ifdef VERIFY_HEAP 721 #ifdef VERIFY_HEAP
769 // This disables verification of weak embedded maps after full GC. 722 // This disables verification of weak embedded objects after full GC.
770 // AddDependentCode can cause a GC, which would observe the state where 723 // AddDependentCode can cause a GC, which would observe the state where
771 // this code is not yet in the depended code lists of the embedded maps. 724 // this code is not yet in the depended code lists of the embedded maps.
772 NoWeakEmbeddedMapsVerificationScope disable_verification_of_embedded_maps; 725 NoWeakObjectVerificationScope disable_verification_of_embedded_objects;
773 #endif 726 #endif
774 for (int i = 0; i < maps.length(); i++) { 727 for (int i = 0; i < maps.length(); i++) {
775 maps.at(i)->AddDependentCode(DependentCode::kWeaklyEmbeddedGroup, code); 728 maps.at(i)->AddDependentCode(DependentCode::kWeaklyEmbeddedGroup, code);
776 } 729 }
730 for (int i = 0; i < objects.length(); i++) {
731 AddWeakObjectToCodeDependency(isolate()->heap(), objects.at(i), code);
732 }
777 } 733 }
778 734
779 735
780 void LCodeGen::PopulateDeoptimizationData(Handle<Code> code) { 736 void LCodeGen::PopulateDeoptimizationData(Handle<Code> code) {
781 int length = deoptimizations_.length(); 737 int length = deoptimizations_.length();
782 if (length == 0) return; 738 if (length == 0) return;
783 Handle<DeoptimizationInputData> data = 739 Handle<DeoptimizationInputData> data =
784 factory()->NewDeoptimizationInputData(length, TENURED); 740 factory()->NewDeoptimizationInputData(length, TENURED);
785 741
786 Handle<ByteArray> translations = 742 Handle<ByteArray> translations =
(...skipping 1108 matching lines...) Expand 10 before | Expand all | Expand 10 after
1895 ASSERT(ToRegister(instr->left()).is(rdx)); 1851 ASSERT(ToRegister(instr->left()).is(rdx));
1896 ASSERT(ToRegister(instr->right()).is(rax)); 1852 ASSERT(ToRegister(instr->right()).is(rax));
1897 ASSERT(ToRegister(instr->result()).is(rax)); 1853 ASSERT(ToRegister(instr->result()).is(rax));
1898 1854
1899 BinaryOpStub stub(instr->op(), NO_OVERWRITE); 1855 BinaryOpStub stub(instr->op(), NO_OVERWRITE);
1900 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr); 1856 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr);
1901 __ nop(); // Signals no inlined code. 1857 __ nop(); // Signals no inlined code.
1902 } 1858 }
1903 1859
1904 1860
1905 int LCodeGen::GetNextEmittedBlock() const {
1906 for (int i = current_block_ + 1; i < graph()->blocks()->length(); ++i) {
1907 if (!chunk_->GetLabel(i)->HasReplacement()) return i;
1908 }
1909 return -1;
1910 }
1911
1912
1913 template<class InstrType> 1861 template<class InstrType>
1914 void LCodeGen::EmitBranch(InstrType instr, Condition cc) { 1862 void LCodeGen::EmitBranch(InstrType instr, Condition cc) {
1915 int left_block = instr->TrueDestination(chunk_); 1863 int left_block = instr->TrueDestination(chunk_);
1916 int right_block = instr->FalseDestination(chunk_); 1864 int right_block = instr->FalseDestination(chunk_);
1917 1865
1918 int next_block = GetNextEmittedBlock(); 1866 int next_block = GetNextEmittedBlock();
1919 1867
1920 if (right_block == left_block || cc == no_condition) { 1868 if (right_block == left_block || cc == no_condition) {
1921 EmitGoto(left_block); 1869 EmitGoto(left_block);
1922 } else if (left_block == next_block) { 1870 } else if (left_block == next_block) {
(...skipping 850 matching lines...) Expand 10 before | Expand all | Expand 10 after
2773 2721
2774 __ bind(&skip_assignment); 2722 __ bind(&skip_assignment);
2775 } 2723 }
2776 2724
2777 2725
2778 void LCodeGen::DoLoadNamedField(LLoadNamedField* instr) { 2726 void LCodeGen::DoLoadNamedField(LLoadNamedField* instr) {
2779 HObjectAccess access = instr->hydrogen()->access(); 2727 HObjectAccess access = instr->hydrogen()->access();
2780 int offset = access.offset(); 2728 int offset = access.offset();
2781 2729
2782 if (access.IsExternalMemory()) { 2730 if (access.IsExternalMemory()) {
2783 ASSERT(!access.representation().IsInteger32());
2784 Register result = ToRegister(instr->result()); 2731 Register result = ToRegister(instr->result());
2785 if (instr->object()->IsConstantOperand()) { 2732 if (instr->object()->IsConstantOperand()) {
2786 ASSERT(result.is(rax)); 2733 ASSERT(result.is(rax));
2787 __ load_rax(ToExternalReference(LConstantOperand::cast(instr->object()))); 2734 __ load_rax(ToExternalReference(LConstantOperand::cast(instr->object())));
2788 } else { 2735 } else {
2789 Register object = ToRegister(instr->object()); 2736 Register object = ToRegister(instr->object());
2790 __ movq(result, MemOperand(object, offset)); 2737 __ Load(result, MemOperand(object, offset), access.representation());
2791 } 2738 }
2792 return; 2739 return;
2793 } 2740 }
2794 2741
2795 Register object = ToRegister(instr->object()); 2742 Register object = ToRegister(instr->object());
2796 if (FLAG_track_double_fields && 2743 if (FLAG_track_double_fields &&
2797 instr->hydrogen()->representation().IsDouble()) { 2744 instr->hydrogen()->representation().IsDouble()) {
2798 XMMRegister result = ToDoubleRegister(instr->result()); 2745 XMMRegister result = ToDoubleRegister(instr->result());
2799 __ movsd(result, FieldOperand(object, offset)); 2746 __ movsd(result, FieldOperand(object, offset));
2800 return; 2747 return;
2801 } 2748 }
2802 2749
2803 Register result = ToRegister(instr->result()); 2750 Register result = ToRegister(instr->result());
2804 if (access.IsInobject()) { 2751 if (!access.IsInobject()) {
2805 if (access.representation().IsInteger32()) {
2806 __ movl(result, FieldOperand(object, offset));
2807 } else {
2808 __ movq(result, FieldOperand(object, offset));
2809 }
2810 } else {
2811 __ movq(result, FieldOperand(object, JSObject::kPropertiesOffset)); 2752 __ movq(result, FieldOperand(object, JSObject::kPropertiesOffset));
2812 if (access.representation().IsInteger32()) { 2753 object = result;
2813 __ movl(result, FieldOperand(result, offset));
2814 } else {
2815 __ movq(result, FieldOperand(result, offset));
2816 }
2817 } 2754 }
2755 __ Load(result, FieldOperand(object, offset), access.representation());
2818 } 2756 }
2819 2757
2820 2758
2821 void LCodeGen::DoLoadNamedGeneric(LLoadNamedGeneric* instr) { 2759 void LCodeGen::DoLoadNamedGeneric(LLoadNamedGeneric* instr) {
2822 ASSERT(ToRegister(instr->object()).is(rax)); 2760 ASSERT(ToRegister(instr->object()).is(rax));
2823 ASSERT(ToRegister(instr->result()).is(rax)); 2761 ASSERT(ToRegister(instr->result()).is(rax));
2824 2762
2825 __ Move(rcx, instr->name()); 2763 __ Move(rcx, instr->name());
2826 Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize(); 2764 Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize();
2827 CallCode(ic, RelocInfo::CODE_TARGET, instr); 2765 CallCode(ic, RelocInfo::CODE_TARGET, instr);
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
2885 2823
2886 2824
2887 void LCodeGen::DoAccessArgumentsAt(LAccessArgumentsAt* instr) { 2825 void LCodeGen::DoAccessArgumentsAt(LAccessArgumentsAt* instr) {
2888 Register arguments = ToRegister(instr->arguments()); 2826 Register arguments = ToRegister(instr->arguments());
2889 Register result = ToRegister(instr->result()); 2827 Register result = ToRegister(instr->result());
2890 2828
2891 if (instr->length()->IsConstantOperand() && 2829 if (instr->length()->IsConstantOperand() &&
2892 instr->index()->IsConstantOperand()) { 2830 instr->index()->IsConstantOperand()) {
2893 int32_t const_index = ToInteger32(LConstantOperand::cast(instr->index())); 2831 int32_t const_index = ToInteger32(LConstantOperand::cast(instr->index()));
2894 int32_t const_length = ToInteger32(LConstantOperand::cast(instr->length())); 2832 int32_t const_length = ToInteger32(LConstantOperand::cast(instr->length()));
2895 int index = (const_length - const_index) + 1; 2833 StackArgumentsAccessor args(arguments, const_length,
2896 __ movq(result, Operand(arguments, index * kPointerSize)); 2834 ARGUMENTS_DONT_CONTAIN_RECEIVER);
2835 __ movq(result, args.GetArgumentOperand(const_index));
2897 } else { 2836 } else {
2898 Register length = ToRegister(instr->length()); 2837 Register length = ToRegister(instr->length());
2899 // There are two words between the frame pointer and the last argument. 2838 // There are two words between the frame pointer and the last argument.
2900 // Subtracting from length accounts for one of them add one more. 2839 // Subtracting from length accounts for one of them add one more.
2901 if (instr->index()->IsRegister()) { 2840 if (instr->index()->IsRegister()) {
2902 __ subl(length, ToRegister(instr->index())); 2841 __ subl(length, ToRegister(instr->index()));
2903 } else { 2842 } else {
2904 __ subl(length, ToOperand(instr->index())); 2843 __ subl(length, ToOperand(instr->index()));
2905 } 2844 }
2906 __ movq(result, 2845 StackArgumentsAccessor args(arguments, length,
2907 Operand(arguments, length, times_pointer_size, kPointerSize)); 2846 ARGUMENTS_DONT_CONTAIN_RECEIVER);
2847 __ movq(result, args.GetArgumentOperand(0));
2908 } 2848 }
2909 } 2849 }
2910 2850
2911 2851
2912 void LCodeGen::DoLoadKeyedExternalArray(LLoadKeyed* instr) { 2852 void LCodeGen::DoLoadKeyedExternalArray(LLoadKeyed* instr) {
2913 ElementsKind elements_kind = instr->elements_kind(); 2853 ElementsKind elements_kind = instr->elements_kind();
2914 LOperand* key = instr->key(); 2854 LOperand* key = instr->key();
2915 if (!key->IsConstantOperand()) { 2855 if (!key->IsConstantOperand()) {
2916 Register key_reg = ToRegister(key); 2856 Register key_reg = ToRegister(key);
2917 // Even though the HLoad/StoreKeyed (in this case) instructions force 2857 // Even though the HLoad/StoreKeyed (in this case) instructions force
(...skipping 183 matching lines...) Expand 10 before | Expand all | Expand 10 after
3101 3041
3102 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize(); 3042 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize();
3103 CallCode(ic, RelocInfo::CODE_TARGET, instr); 3043 CallCode(ic, RelocInfo::CODE_TARGET, instr);
3104 } 3044 }
3105 3045
3106 3046
3107 void LCodeGen::DoArgumentsElements(LArgumentsElements* instr) { 3047 void LCodeGen::DoArgumentsElements(LArgumentsElements* instr) {
3108 Register result = ToRegister(instr->result()); 3048 Register result = ToRegister(instr->result());
3109 3049
3110 if (instr->hydrogen()->from_inlined()) { 3050 if (instr->hydrogen()->from_inlined()) {
3111 __ lea(result, Operand(rsp, -2 * kPointerSize)); 3051 __ lea(result, Operand(rsp, -kFPOnStackSize + -kPCOnStackSize));
3112 } else { 3052 } else {
3113 // Check for arguments adapter frame. 3053 // Check for arguments adapter frame.
3114 Label done, adapted; 3054 Label done, adapted;
3115 __ movq(result, Operand(rbp, StandardFrameConstants::kCallerFPOffset)); 3055 __ movq(result, Operand(rbp, StandardFrameConstants::kCallerFPOffset));
3116 __ Cmp(Operand(result, StandardFrameConstants::kContextOffset), 3056 __ Cmp(Operand(result, StandardFrameConstants::kContextOffset),
3117 Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR)); 3057 Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR));
3118 __ j(equal, &adapted, Label::kNear); 3058 __ j(equal, &adapted, Label::kNear);
3119 3059
3120 // No arguments adaptor frame. 3060 // No arguments adaptor frame.
3121 __ movq(result, rbp); 3061 __ movq(result, rbp);
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after
3223 __ push(receiver); 3163 __ push(receiver);
3224 __ movq(receiver, length); 3164 __ movq(receiver, length);
3225 3165
3226 // Loop through the arguments pushing them onto the execution 3166 // Loop through the arguments pushing them onto the execution
3227 // stack. 3167 // stack.
3228 Label invoke, loop; 3168 Label invoke, loop;
3229 // length is a small non-negative integer, due to the test above. 3169 // length is a small non-negative integer, due to the test above.
3230 __ testl(length, length); 3170 __ testl(length, length);
3231 __ j(zero, &invoke, Label::kNear); 3171 __ j(zero, &invoke, Label::kNear);
3232 __ bind(&loop); 3172 __ bind(&loop);
3233 __ push(Operand(elements, length, times_pointer_size, 1 * kPointerSize)); 3173 StackArgumentsAccessor args(elements, length,
3174 ARGUMENTS_DONT_CONTAIN_RECEIVER);
3175 __ push(args.GetArgumentOperand(0));
3234 __ decl(length); 3176 __ decl(length);
3235 __ j(not_zero, &loop); 3177 __ j(not_zero, &loop);
3236 3178
3237 // Invoke the function. 3179 // Invoke the function.
3238 __ bind(&invoke); 3180 __ bind(&invoke);
3239 ASSERT(instr->HasPointerMap()); 3181 ASSERT(instr->HasPointerMap());
3240 LPointerMap* pointers = instr->pointer_map(); 3182 LPointerMap* pointers = instr->pointer_map();
3241 RecordPosition(pointers->position()); 3183 RecordPosition(pointers->position());
3242 SafepointGenerator safepoint_generator( 3184 SafepointGenerator safepoint_generator(
3243 this, pointers, Safepoint::kLazyDeopt); 3185 this, pointers, Safepoint::kLazyDeopt);
(...skipping 655 matching lines...) Expand 10 before | Expand all | Expand 10 after
3899 CallCode(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL, instr); 3841 CallCode(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL, instr);
3900 __ bind(&done); 3842 __ bind(&done);
3901 } else { 3843 } else {
3902 ArrayNArgumentsConstructorStub stub(kind, context_mode, override_mode); 3844 ArrayNArgumentsConstructorStub stub(kind, context_mode, override_mode);
3903 CallCode(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL, instr); 3845 CallCode(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL, instr);
3904 } 3846 }
3905 } 3847 }
3906 3848
3907 3849
3908 void LCodeGen::DoCallRuntime(LCallRuntime* instr) { 3850 void LCodeGen::DoCallRuntime(LCallRuntime* instr) {
3909 CallRuntime(instr->function(), instr->arity(), instr); 3851 CallRuntime(instr->function(), instr->arity(), instr, instr->save_doubles());
3910 } 3852 }
3911 3853
3912 3854
3913 void LCodeGen::DoStoreCodeEntry(LStoreCodeEntry* instr) { 3855 void LCodeGen::DoStoreCodeEntry(LStoreCodeEntry* instr) {
3914 Register function = ToRegister(instr->function()); 3856 Register function = ToRegister(instr->function());
3915 Register code_object = ToRegister(instr->code_object()); 3857 Register code_object = ToRegister(instr->code_object());
3916 __ lea(code_object, FieldOperand(code_object, Code::kHeaderSize)); 3858 __ lea(code_object, FieldOperand(code_object, Code::kHeaderSize));
3917 __ movq(FieldOperand(function, JSFunction::kCodeEntryOffset), code_object); 3859 __ movq(FieldOperand(function, JSFunction::kCodeEntryOffset), code_object);
3918 } 3860 }
3919 3861
3920 3862
3921 void LCodeGen::DoInnerAllocatedObject(LInnerAllocatedObject* instr) { 3863 void LCodeGen::DoInnerAllocatedObject(LInnerAllocatedObject* instr) {
3922 Register result = ToRegister(instr->result()); 3864 Register result = ToRegister(instr->result());
3923 Register base = ToRegister(instr->base_object()); 3865 Register base = ToRegister(instr->base_object());
3924 __ lea(result, Operand(base, instr->offset())); 3866 __ lea(result, Operand(base, instr->offset()));
3925 } 3867 }
3926 3868
3927 3869
3928 void LCodeGen::DoStoreNamedField(LStoreNamedField* instr) { 3870 void LCodeGen::DoStoreNamedField(LStoreNamedField* instr) {
3929 Representation representation = instr->representation(); 3871 Representation representation = instr->representation();
3930 3872
3931 HObjectAccess access = instr->hydrogen()->access(); 3873 HObjectAccess access = instr->hydrogen()->access();
3932 int offset = access.offset(); 3874 int offset = access.offset();
3933 3875
3934 if (access.IsExternalMemory()) { 3876 if (access.IsExternalMemory()) {
3935 ASSERT(!access.representation().IsInteger32());
3936 ASSERT(!instr->hydrogen()->NeedsWriteBarrier()); 3877 ASSERT(!instr->hydrogen()->NeedsWriteBarrier());
3937 Register value = ToRegister(instr->value()); 3878 Register value = ToRegister(instr->value());
3938 if (instr->object()->IsConstantOperand()) { 3879 if (instr->object()->IsConstantOperand()) {
3939 ASSERT(value.is(rax)); 3880 ASSERT(value.is(rax));
3881 ASSERT(!access.representation().IsSpecialization());
3940 LConstantOperand* object = LConstantOperand::cast(instr->object()); 3882 LConstantOperand* object = LConstantOperand::cast(instr->object());
3941 __ store_rax(ToExternalReference(object)); 3883 __ store_rax(ToExternalReference(object));
3942 } else { 3884 } else {
3943 Register object = ToRegister(instr->object()); 3885 Register object = ToRegister(instr->object());
3944 __ movq(MemOperand(object, offset), value); 3886 __ Store(MemOperand(object, offset), value, representation);
3945 } 3887 }
3946 return; 3888 return;
3947 } 3889 }
3948 3890
3949 Register object = ToRegister(instr->object()); 3891 Register object = ToRegister(instr->object());
3950 Handle<Map> transition = instr->transition(); 3892 Handle<Map> transition = instr->transition();
3951 3893
3952 if (FLAG_track_fields && representation.IsSmi()) { 3894 if (FLAG_track_fields && representation.IsSmi()) {
3953 if (instr->value()->IsConstantOperand()) { 3895 if (instr->value()->IsConstantOperand()) {
3954 LConstantOperand* operand_value = LConstantOperand::cast(instr->value()); 3896 LConstantOperand* operand_value = LConstantOperand::cast(instr->value());
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
4003 3945
4004 Register write_register = object; 3946 Register write_register = object;
4005 if (!access.IsInobject()) { 3947 if (!access.IsInobject()) {
4006 write_register = ToRegister(instr->temp()); 3948 write_register = ToRegister(instr->temp());
4007 __ movq(write_register, FieldOperand(object, JSObject::kPropertiesOffset)); 3949 __ movq(write_register, FieldOperand(object, JSObject::kPropertiesOffset));
4008 } 3950 }
4009 3951
4010 if (instr->value()->IsConstantOperand()) { 3952 if (instr->value()->IsConstantOperand()) {
4011 LConstantOperand* operand_value = LConstantOperand::cast(instr->value()); 3953 LConstantOperand* operand_value = LConstantOperand::cast(instr->value());
4012 if (operand_value->IsRegister()) { 3954 if (operand_value->IsRegister()) {
4013 if (access.representation().IsInteger32()) { 3955 Register value = ToRegister(operand_value);
4014 __ movl(FieldOperand(write_register, offset), 3956 __ Store(FieldOperand(write_register, offset), value, representation);
4015 ToRegister(operand_value));
4016 } else {
4017 __ movq(FieldOperand(write_register, offset),
4018 ToRegister(operand_value));
4019 }
4020 } else { 3957 } else {
4021 Handle<Object> handle_value = ToHandle(operand_value); 3958 Handle<Object> handle_value = ToHandle(operand_value);
4022 ASSERT(!instr->hydrogen()->NeedsWriteBarrier()); 3959 ASSERT(!instr->hydrogen()->NeedsWriteBarrier());
4023 __ Move(FieldOperand(write_register, offset), handle_value); 3960 __ Move(FieldOperand(write_register, offset), handle_value);
4024 } 3961 }
4025 } else { 3962 } else {
4026 if (access.representation().IsInteger32()) { 3963 Register value = ToRegister(instr->value());
4027 __ movl(FieldOperand(write_register, offset), ToRegister(instr->value())); 3964 __ Store(FieldOperand(write_register, offset), value, representation);
4028 } else {
4029 __ movq(FieldOperand(write_register, offset), ToRegister(instr->value()));
4030 }
4031 } 3965 }
4032 3966
4033 if (instr->hydrogen()->NeedsWriteBarrier()) { 3967 if (instr->hydrogen()->NeedsWriteBarrier()) {
4034 Register value = ToRegister(instr->value()); 3968 Register value = ToRegister(instr->value());
4035 Register temp = access.IsInobject() ? ToRegister(instr->temp()) : object; 3969 Register temp = access.IsInobject() ? ToRegister(instr->temp()) : object;
4036 // Update the write barrier for the object for in-object properties. 3970 // Update the write barrier for the object for in-object properties.
4037 __ RecordWriteField(write_register, 3971 __ RecordWriteField(write_register,
4038 offset, 3972 offset,
4039 value, 3973 value,
4040 temp, 3974 temp,
(...skipping 1471 matching lines...) Expand 10 before | Expand all | Expand 10 after
5512 FixedArray::kHeaderSize - kPointerSize)); 5446 FixedArray::kHeaderSize - kPointerSize));
5513 __ bind(&done); 5447 __ bind(&done);
5514 } 5448 }
5515 5449
5516 5450
5517 #undef __ 5451 #undef __
5518 5452
5519 } } // namespace v8::internal 5453 } } // namespace v8::internal
5520 5454
5521 #endif // V8_TARGET_ARCH_X64 5455 #endif // V8_TARGET_ARCH_X64
OLDNEW
« no previous file with comments | « src/x64/lithium-codegen-x64.h ('k') | src/x64/lithium-x64.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698