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

Side by Side Diff: src/x64/ic-x64.cc

Issue 160272: X64: Added inline keyed load/store and a bunch of other missing functions. (Closed)
Patch Set: Addressed review comments, and fixed bugs introduced by updating. Created 11 years, 4 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
« no previous file with comments | « src/x64/codegen-x64.cc ('k') | src/x64/macro-assembler-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 2009 the V8 project authors. All rights reserved. 1 // Copyright 2009 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 141 matching lines...) Expand 10 before | Expand all | Expand 10 after
152 __ j(zero, &done); 152 __ j(zero, &done);
153 // Check if the object has been loaded. 153 // Check if the object has been loaded.
154 __ movq(kScratchRegister, FieldOperand(value, JSFunction::kMapOffset)); 154 __ movq(kScratchRegister, FieldOperand(value, JSFunction::kMapOffset));
155 __ testb(FieldOperand(kScratchRegister, Map::kBitField2Offset), 155 __ testb(FieldOperand(kScratchRegister, Map::kBitField2Offset),
156 Immediate(1 << Map::kNeedsLoading)); 156 Immediate(1 << Map::kNeedsLoading));
157 __ j(not_zero, miss); 157 __ j(not_zero, miss);
158 __ bind(&done); 158 __ bind(&done);
159 } 159 }
160 160
161 161
162 // One byte opcode for test eax,0xXXXXXXXX.
163 static const byte kTestEaxByte = 0xA9;
164
165
166 static bool PatchInlinedMapCheck(Address address, Object* map) {
167 // Arguments are address of start of call sequence that called
168 // the IC,
169 Address test_instruction_address =
170 address + Assembler::kTargetAddrToReturnAddrDist;
171 // The keyed load has a fast inlined case if the IC call instruction
172 // is immediately followed by a test instruction.
173 if (*test_instruction_address != kTestEaxByte) return false;
174
175 // Fetch the offset from the test instruction to the map compare
176 // instructions (starting with the 64-bit immediate mov of the map
177 // address). This offset is stored in the last 4 bytes of the 5
178 // byte test instruction.
179 Address delta_address = test_instruction_address + 1;
180 int delta = *reinterpret_cast<int*>(delta_address);
181 // Compute the map address. The map address is in the last 8 bytes
182 // of the 10-byte immediate mov instruction (incl. REX prefix), so we add 2
183 // to the offset to get the map address.
184 Address map_address = test_instruction_address + delta + 2;
185 // Patch the map check.
186 *(reinterpret_cast<Object**>(map_address)) = map;
187 return true;
188 }
189
190
191 bool KeyedLoadIC::PatchInlinedLoad(Address address, Object* map) {
192 return PatchInlinedMapCheck(address, map);
193 }
194
195
196 bool KeyedStoreIC::PatchInlinedStore(Address address, Object* map) {
197 return PatchInlinedMapCheck(address, map);
198 }
199
200
162 void KeyedLoadIC::ClearInlinedVersion(Address address) { 201 void KeyedLoadIC::ClearInlinedVersion(Address address) {
163 // TODO(X64): Implement this when LoadIC is enabled. 202 // Insert null as the map to check for to make sure the map check fails
164 } 203 // sending control flow to the IC instead of the inlined version.
165 204 PatchInlinedLoad(address, Heap::null_value());
166 void KeyedStoreIC::ClearInlinedVersion(Address address) {
167 // TODO(X64): Implement this when LoadIC is enabled.
168 }
169
170 void KeyedStoreIC::RestoreInlinedVersion(Address address) {
171 UNIMPLEMENTED();
172 } 205 }
173 206
174 207
208 void KeyedStoreIC::ClearInlinedVersion(Address address) {
209 // Insert null as the elements map to check for. This will make
210 // sure that the elements fast-case map check fails so that control
211 // flows to the IC instead of the inlined version.
212 PatchInlinedStore(address, Heap::null_value());
213 }
214
215
216 void KeyedStoreIC::RestoreInlinedVersion(Address address) {
217 // Restore the fast-case elements map check so that the inlined
218 // version can be used again.
219 PatchInlinedStore(address, Heap::fixed_array_map());
220 }
221
222
175 void KeyedLoadIC::Generate(MacroAssembler* masm, 223 void KeyedLoadIC::Generate(MacroAssembler* masm,
176 ExternalReference const& f) { 224 ExternalReference const& f) {
177 // ----------- S t a t e ------------- 225 // ----------- S t a t e -------------
178 // -- rsp[0] : return address 226 // -- rsp[0] : return address
179 // -- rsp[8] : name 227 // -- rsp[8] : name
180 // -- rsp[16] : receiver 228 // -- rsp[16] : receiver
181 // ----------------------------------- 229 // -----------------------------------
182 230
183 __ movq(rax, Operand(rsp, kPointerSize)); 231 __ movq(rax, Operand(rsp, kPointerSize));
184 __ movq(rcx, Operand(rsp, 2 * kPointerSize)); 232 __ movq(rcx, Operand(rsp, 2 * kPointerSize));
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after
303 void KeyedLoadIC::GenerateMiss(MacroAssembler* masm) { 351 void KeyedLoadIC::GenerateMiss(MacroAssembler* masm) {
304 // ----------- S t a t e ------------- 352 // ----------- S t a t e -------------
305 // -- rsp[0] : return address 353 // -- rsp[0] : return address
306 // -- rsp[8] : name 354 // -- rsp[8] : name
307 // -- rsp[16] : receiver 355 // -- rsp[16] : receiver
308 // ----------------------------------- 356 // -----------------------------------
309 Generate(masm, ExternalReference(IC_Utility(kKeyedLoadIC_Miss))); 357 Generate(masm, ExternalReference(IC_Utility(kKeyedLoadIC_Miss)));
310 } 358 }
311 359
312 360
313 bool KeyedLoadIC::PatchInlinedLoad(Address address, Object* map) {
314 // Never patch the map in the map check, so the check always fails.
315 return false;
316 }
317
318
319 bool KeyedStoreIC::PatchInlinedStore(Address address, Object* map) {
320 // Never patch the map in the map check, so the check always fails.
321 return false;
322 }
323
324
325 void KeyedStoreIC::Generate(MacroAssembler* masm, ExternalReference const& f) { 361 void KeyedStoreIC::Generate(MacroAssembler* masm, ExternalReference const& f) {
326 // ----------- S t a t e ------------- 362 // ----------- S t a t e -------------
327 // -- rax : value 363 // -- rax : value
328 // -- rsp[0] : return address 364 // -- rsp[0] : return address
329 // -- rsp[8] : key 365 // -- rsp[8] : key
330 // -- rsp[16] : receiver 366 // -- rsp[16] : receiver
331 // ----------------------------------- 367 // -----------------------------------
332 368
333 __ pop(rcx); 369 __ pop(rcx);
334 __ push(Operand(rsp, 1 * kPointerSize)); // receiver 370 __ push(Operand(rsp, 1 * kPointerSize)); // receiver
(...skipping 197 matching lines...) Expand 10 before | Expand all | Expand 10 after
532 Generate(masm, argc, ExternalReference(IC_Utility(kCallIC_Miss))); 568 Generate(masm, argc, ExternalReference(IC_Utility(kCallIC_Miss)));
533 } 569 }
534 570
535 571
536 // The offset from the inlined patch site to the start of the 572 // The offset from the inlined patch site to the start of the
537 // inlined load instruction. 573 // inlined load instruction.
538 const int LoadIC::kOffsetToLoadInstruction = 20; 574 const int LoadIC::kOffsetToLoadInstruction = 20;
539 575
540 576
541 void LoadIC::ClearInlinedVersion(Address address) { 577 void LoadIC::ClearInlinedVersion(Address address) {
542 // TODO(X64): Implement this when LoadIC is enabled. 578 // Reset the map check of the inlined inobject property load (if
579 // present) to guarantee failure by holding an invalid map (the null
580 // value). The offset can be patched to anything.
581 PatchInlinedLoad(address, Heap::null_value(), kMaxInt);
543 } 582 }
544 583
545 584
546 void LoadIC::Generate(MacroAssembler* masm, ExternalReference const& f) { 585 void LoadIC::Generate(MacroAssembler* masm, ExternalReference const& f) {
547 // ----------- S t a t e ------------- 586 // ----------- S t a t e -------------
548 // -- rcx : name 587 // -- rcx : name
549 // -- rsp[0] : return address 588 // -- rsp[0] : return address
550 // -- rsp[8] : receiver 589 // -- rsp[8] : receiver
551 // ----------------------------------- 590 // -----------------------------------
552 591
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
598 // -- rsp[8] : receiver 637 // -- rsp[8] : receiver
599 // ----------------------------------- 638 // -----------------------------------
600 639
601 Generate(masm, ExternalReference(IC_Utility(kLoadIC_Miss))); 640 Generate(masm, ExternalReference(IC_Utility(kLoadIC_Miss)));
602 } 641 }
603 642
604 void LoadIC::GenerateNormal(MacroAssembler* masm) { 643 void LoadIC::GenerateNormal(MacroAssembler* masm) {
605 Generate(masm, ExternalReference(IC_Utility(kLoadIC_Miss))); 644 Generate(masm, ExternalReference(IC_Utility(kLoadIC_Miss)));
606 } 645 }
607 646
647
608 void LoadIC::GenerateStringLength(MacroAssembler* masm) { 648 void LoadIC::GenerateStringLength(MacroAssembler* masm) {
609 Generate(masm, ExternalReference(IC_Utility(kLoadIC_Miss))); 649 Generate(masm, ExternalReference(IC_Utility(kLoadIC_Miss)));
610 } 650 }
611 651
612 bool LoadIC::PatchInlinedLoad(Address address, Object* map, int index) { 652
613 // TODO(X64): Implement this function. Until then, the code is not patched. 653 bool LoadIC::PatchInlinedLoad(Address address, Object* map, int offset) {
614 return false; 654 // The address of the instruction following the call.
655 Address test_instruction_address =
656 address + Assembler::kTargetAddrToReturnAddrDist;
657 // If the instruction following the call is not a test eax, nothing
658 // was inlined.
659 if (*test_instruction_address != kTestEaxByte) return false;
660
661 Address delta_address = test_instruction_address + 1;
662 // The delta to the start of the map check instruction.
663 int delta = *reinterpret_cast<int*>(delta_address);
664
665 // The map address is the last 8 bytes of the 10-byte
666 // immediate move instruction, so we add 2 to get the
667 // offset to the last 8 bytes.
668 Address map_address = test_instruction_address + delta + 2;
669 *(reinterpret_cast<Object**>(map_address)) = map;
670
671 // The offset is in the 32-bit displacement of a seven byte
672 // memory-to-register move instruction (REX.W 0x88 ModR/M disp32),
673 // so we add 3 to get the offset of the displacement.
674 Address offset_address =
675 test_instruction_address + delta + kOffsetToLoadInstruction + 3;
676 *reinterpret_cast<int*>(offset_address) = offset - kHeapObjectTag;
677 return true;
615 } 678 }
616 679
617 void StoreIC::Generate(MacroAssembler* masm, ExternalReference const& f) { 680 void StoreIC::Generate(MacroAssembler* masm, ExternalReference const& f) {
618 // ----------- S t a t e ------------- 681 // ----------- S t a t e -------------
619 // -- rax : value 682 // -- rax : value
620 // -- rcx : name 683 // -- rcx : name
621 // -- rsp[0] : return address 684 // -- rsp[0] : return address
622 // -- rsp[8] : receiver 685 // -- rsp[8] : receiver
623 // ----------------------------------- 686 // -----------------------------------
624 __ pop(rbx); 687 __ pop(rbx);
(...skipping 27 matching lines...) Expand all
652 715
653 void StoreIC::GenerateMegamorphic(MacroAssembler* masm) { 716 void StoreIC::GenerateMegamorphic(MacroAssembler* masm) {
654 Generate(masm, ExternalReference(IC_Utility(kStoreIC_Miss))); 717 Generate(masm, ExternalReference(IC_Utility(kStoreIC_Miss)));
655 } 718 }
656 719
657 720
658 #undef __ 721 #undef __
659 722
660 723
661 } } // namespace v8::internal 724 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/x64/codegen-x64.cc ('k') | src/x64/macro-assembler-x64.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698