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

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

Issue 660095: Merge revision 3813 to 3930 from bleeding_edge to partial snapshots branch. (Closed) Base URL: http://v8.googlecode.com/svn/branches/experimental/partial_snapshots/
Patch Set: '' Created 10 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/full-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 2010 the V8 project authors. All rights reserved. 1 // Copyright 2010 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 194 matching lines...) Expand 10 before | Expand all | Expand 10 after
205 } 205 }
206 206
207 207
208 void KeyedStoreIC::RestoreInlinedVersion(Address address) { 208 void KeyedStoreIC::RestoreInlinedVersion(Address address) {
209 // Restore the fast-case elements map check so that the inlined 209 // Restore the fast-case elements map check so that the inlined
210 // version can be used again. 210 // version can be used again.
211 PatchInlinedStore(address, Heap::fixed_array_map()); 211 PatchInlinedStore(address, Heap::fixed_array_map());
212 } 212 }
213 213
214 214
215 void KeyedLoadIC::Generate(MacroAssembler* masm, 215 void KeyedLoadIC::GenerateMiss(MacroAssembler* masm) {
216 ExternalReference const& f) {
217 // ----------- S t a t e ------------- 216 // ----------- S t a t e -------------
218 // -- rsp[0] : return address 217 // -- rsp[0] : return address
219 // -- rsp[8] : name 218 // -- rsp[8] : name
220 // -- rsp[16] : receiver 219 // -- rsp[16] : receiver
221 // ----------------------------------- 220 // -----------------------------------
222 221
223 __ movq(rax, Operand(rsp, kPointerSize));
224 __ movq(rcx, Operand(rsp, 2 * kPointerSize));
225 __ pop(rbx); 222 __ pop(rbx);
226 __ push(rcx); // receiver 223 __ push(Operand(rsp, 1 * kPointerSize)); // receiver
227 __ push(rax); // name 224 __ push(Operand(rsp, 1 * kPointerSize)); // name
228 __ push(rbx); // return address 225 __ push(rbx); // return address
229 226
230 // Perform tail call to the entry. 227 // Perform tail call to the entry.
231 __ TailCallRuntime(f, 2, 1); 228 __ TailCallRuntime(ExternalReference(IC_Utility(kKeyedLoadIC_Miss)), 2, 1);
229 }
230
231
232 void KeyedLoadIC::GenerateRuntimeGetProperty(MacroAssembler* masm) {
233 // ----------- S t a t e -------------
234 // -- rsp[0] : return address
235 // -- rsp[8] : name
236 // -- rsp[16] : receiver
237 // -----------------------------------
238
239 __ pop(rbx);
240 __ push(Operand(rsp, 1 * kPointerSize)); // receiver
241 __ push(Operand(rsp, 1 * kPointerSize)); // name
242 __ push(rbx); // return address
243
244 // Perform tail call to the entry.
245 __ TailCallRuntime(ExternalReference(Runtime::kKeyedGetProperty), 2, 1);
232 } 246 }
233 247
234 248
235 void KeyedLoadIC::GenerateGeneric(MacroAssembler* masm) { 249 void KeyedLoadIC::GenerateGeneric(MacroAssembler* masm) {
236 // ----------- S t a t e ------------- 250 // ----------- S t a t e -------------
237 // -- rsp[0] : return address 251 // -- rsp[0] : return address
238 // -- rsp[8] : name 252 // -- rsp[8] : name
239 // -- rsp[16] : receiver 253 // -- rsp[16] : receiver
240 // ----------------------------------- 254 // -----------------------------------
241 Label slow, check_string, index_int, index_string; 255 Label slow, check_string, index_int, index_string;
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
294 __ cmpl(rax, FieldOperand(rcx, PixelArray::kLengthOffset)); 308 __ cmpl(rax, FieldOperand(rcx, PixelArray::kLengthOffset));
295 __ j(above_equal, &slow); 309 __ j(above_equal, &slow);
296 __ movq(rcx, FieldOperand(rcx, PixelArray::kExternalPointerOffset)); 310 __ movq(rcx, FieldOperand(rcx, PixelArray::kExternalPointerOffset));
297 __ movzxbq(rax, Operand(rcx, rax, times_1, 0)); 311 __ movzxbq(rax, Operand(rcx, rax, times_1, 0));
298 __ Integer32ToSmi(rax, rax); 312 __ Integer32ToSmi(rax, rax);
299 __ ret(0); 313 __ ret(0);
300 314
301 // Slow case: Load name and receiver from stack and jump to runtime. 315 // Slow case: Load name and receiver from stack and jump to runtime.
302 __ bind(&slow); 316 __ bind(&slow);
303 __ IncrementCounter(&Counters::keyed_load_generic_slow, 1); 317 __ IncrementCounter(&Counters::keyed_load_generic_slow, 1);
304 Generate(masm, ExternalReference(Runtime::kKeyedGetProperty)); 318 GenerateRuntimeGetProperty(masm);
305 __ bind(&check_string); 319 __ bind(&check_string);
306 // The key is not a smi. 320 // The key is not a smi.
307 // Is it a string? 321 // Is it a string?
308 __ CmpObjectType(rax, FIRST_NONSTRING_TYPE, rdx); 322 __ CmpObjectType(rax, FIRST_NONSTRING_TYPE, rdx);
309 __ j(above_equal, &slow); 323 __ j(above_equal, &slow);
310 // Is the string an array index, with cached numeric value? 324 // Is the string an array index, with cached numeric value?
311 __ movl(rbx, FieldOperand(rax, String::kHashFieldOffset)); 325 __ movl(rbx, FieldOperand(rax, String::kHashFieldOffset));
312 __ testl(rbx, Immediate(String::kIsArrayIndexMask)); 326 __ testl(rbx, Immediate(String::kIsArrayIndexMask));
313 327
314 // Is the string a symbol? 328 // Is the string a symbol?
(...skipping 216 matching lines...) Expand 10 before | Expand all | Expand 10 after
531 // If we fail allocation of the HeapNumber, we still have a value on 545 // If we fail allocation of the HeapNumber, we still have a value on
532 // top of the FPU stack. Remove it. 546 // top of the FPU stack. Remove it.
533 __ bind(&failed_allocation); 547 __ bind(&failed_allocation);
534 __ ffree(); 548 __ ffree();
535 __ fincstp(); 549 __ fincstp();
536 // Fall through to slow case. 550 // Fall through to slow case.
537 551
538 // Slow case: Load name and receiver from stack and jump to runtime. 552 // Slow case: Load name and receiver from stack and jump to runtime.
539 __ bind(&slow); 553 __ bind(&slow);
540 __ IncrementCounter(&Counters::keyed_load_external_array_slow, 1); 554 __ IncrementCounter(&Counters::keyed_load_external_array_slow, 1);
541 Generate(masm, ExternalReference(Runtime::kKeyedGetProperty)); 555 GenerateRuntimeGetProperty(masm);
542 } 556 }
543 557
544 558
545 void KeyedLoadIC::GenerateMiss(MacroAssembler* masm) { 559 void KeyedLoadIC::GenerateIndexedInterceptor(MacroAssembler* masm) {
546 // ----------- S t a t e ------------- 560 // ----------- S t a t e -------------
547 // -- rsp[0] : return address 561 // -- rsp[0] : return address
548 // -- rsp[8] : name 562 // -- rsp[8] : key
549 // -- rsp[16] : receiver 563 // -- rsp[16] : receiver
550 // ----------------------------------- 564 // -----------------------------------
551 Generate(masm, ExternalReference(IC_Utility(kKeyedLoadIC_Miss))); 565 Label slow;
566
567 // Load key and receiver.
568 __ movq(rax, Operand(rsp, kPointerSize));
569 __ movq(rcx, Operand(rsp, 2 * kPointerSize));
570
571 // Check that the receiver isn't a smi.
572 __ JumpIfSmi(rcx, &slow);
573
574 // Check that the key is a smi.
575 __ JumpIfNotSmi(rax, &slow);
576
577 // Get the map of the receiver.
578 __ movq(rdx, FieldOperand(rcx, HeapObject::kMapOffset));
579
580 // Check that it has indexed interceptor and access checks
581 // are not enabled for this object.
582 __ movb(rdx, FieldOperand(rdx, Map::kBitFieldOffset));
583 __ andb(rdx, Immediate(kSlowCaseBitFieldMask));
584 __ cmpb(rdx, Immediate(1 << Map::kHasIndexedInterceptor));
585 __ j(not_zero, &slow);
586
587 // Everything is fine, call runtime.
588 __ pop(rdx);
589 __ push(rcx); // receiver
590 __ push(rax); // key
591 __ push(rdx); // return address
592
593 // Perform tail call to the entry.
594 __ TailCallRuntime(ExternalReference(
595 IC_Utility(kKeyedLoadPropertyWithInterceptor)), 2, 1);
596
597 __ bind(&slow);
598 GenerateMiss(masm);
552 } 599 }
553 600
554 601
555 void KeyedStoreIC::Generate(MacroAssembler* masm, ExternalReference const& f) { 602 void KeyedStoreIC::GenerateMiss(MacroAssembler* masm) {
556 // ----------- S t a t e ------------- 603 // ----------- S t a t e -------------
557 // -- rax : value 604 // -- rax : value
558 // -- rsp[0] : return address 605 // -- rsp[0] : return address
559 // -- rsp[8] : key 606 // -- rsp[8] : key
560 // -- rsp[16] : receiver 607 // -- rsp[16] : receiver
561 // ----------------------------------- 608 // -----------------------------------
562 609
563 __ pop(rcx); 610 __ pop(rcx);
564 __ push(Operand(rsp, 1 * kPointerSize)); // receiver 611 __ push(Operand(rsp, 1 * kPointerSize)); // receiver
565 __ push(Operand(rsp, 1 * kPointerSize)); // key 612 __ push(Operand(rsp, 1 * kPointerSize)); // key
566 __ push(rax); // value 613 __ push(rax); // value
567 __ push(rcx); // return address 614 __ push(rcx); // return address
568 615
569 // Do tail-call to runtime routine. 616 // Do tail-call to runtime routine.
570 __ TailCallRuntime(f, 3, 1); 617 __ TailCallRuntime(ExternalReference(IC_Utility(kKeyedStoreIC_Miss)), 3, 1);
571 } 618 }
572 619
573 620
574 void KeyedStoreIC::GenerateExtendStorage(MacroAssembler* masm) { 621 void KeyedStoreIC::GenerateRuntimeSetProperty(MacroAssembler* masm) {
575 // ----------- S t a t e ------------- 622 // ----------- S t a t e -------------
576 // -- rax : value 623 // -- rax : value
577 // -- rcx : transition map
578 // -- rsp[0] : return address 624 // -- rsp[0] : return address
579 // -- rsp[8] : key 625 // -- rsp[8] : key
580 // -- rsp[16] : receiver 626 // -- rsp[16] : receiver
581 // ----------------------------------- 627 // -----------------------------------
582 628
583 __ pop(rbx); 629 __ pop(rcx);
584 __ push(Operand(rsp, 1 * kPointerSize)); // receiver 630 __ push(Operand(rsp, 1 * kPointerSize)); // receiver
585 __ push(rcx); // transition map 631 __ push(Operand(rsp, 1 * kPointerSize)); // key
586 __ push(rax); // value 632 __ push(rax); // value
587 __ push(rbx); // return address 633 __ push(rcx); // return address
588 634
589 // Do tail-call to runtime routine. 635 // Do tail-call to runtime routine.
590 __ TailCallRuntime( 636 __ TailCallRuntime(ExternalReference(Runtime::kSetProperty), 3, 1);
591 ExternalReference(IC_Utility(kSharedStoreIC_ExtendStorage)), 3, 1);
592 } 637 }
593 638
594 639
595 void KeyedStoreIC::GenerateGeneric(MacroAssembler* masm) { 640 void KeyedStoreIC::GenerateGeneric(MacroAssembler* masm) {
596 // ----------- S t a t e ------------- 641 // ----------- S t a t e -------------
597 // -- rax : value 642 // -- rax : value
598 // -- rsp[0] : return address 643 // -- rsp[0] : return address
599 // -- rsp[8] : key 644 // -- rsp[8] : key
600 // -- rsp[16] : receiver 645 // -- rsp[16] : receiver
601 // ----------------------------------- 646 // -----------------------------------
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
635 // Untag the key (for checking against untagged length in the fixed array). 680 // Untag the key (for checking against untagged length in the fixed array).
636 __ SmiToInteger32(rdx, rbx); 681 __ SmiToInteger32(rdx, rbx);
637 __ cmpl(rdx, FieldOperand(rcx, Array::kLengthOffset)); 682 __ cmpl(rdx, FieldOperand(rcx, Array::kLengthOffset));
638 // rax: value 683 // rax: value
639 // rcx: FixedArray 684 // rcx: FixedArray
640 // rbx: index (as a smi) 685 // rbx: index (as a smi)
641 __ j(below, &fast); 686 __ j(below, &fast);
642 687
643 // Slow case: call runtime. 688 // Slow case: call runtime.
644 __ bind(&slow); 689 __ bind(&slow);
645 Generate(masm, ExternalReference(Runtime::kSetProperty)); 690 GenerateRuntimeSetProperty(masm);
646 691
647 // Check whether the elements is a pixel array. 692 // Check whether the elements is a pixel array.
648 // rax: value 693 // rax: value
649 // rcx: elements array 694 // rcx: elements array
650 // rbx: index (as a smi), zero-extended. 695 // rbx: index (as a smi), zero-extended.
651 __ bind(&check_pixel_array); 696 __ bind(&check_pixel_array);
652 __ CompareRoot(FieldOperand(rcx, HeapObject::kMapOffset), 697 __ CompareRoot(FieldOperand(rcx, HeapObject::kMapOffset),
653 Heap::kPixelArrayMapRootIndex); 698 Heap::kPixelArrayMapRootIndex);
654 __ j(not_equal, &slow); 699 __ j(not_equal, &slow);
655 // Check that the value is a smi. If a conversion is needed call into the 700 // Check that the value is a smi. If a conversion is needed call into the
(...skipping 243 matching lines...) Expand 10 before | Expand all | Expand 10 after
899 default: 944 default:
900 UNREACHABLE(); 945 UNREACHABLE();
901 break; 946 break;
902 } 947 }
903 __ movq(rax, rdx); // Return the original value. 948 __ movq(rax, rdx); // Return the original value.
904 __ ret(0); 949 __ ret(0);
905 } 950 }
906 951
907 // Slow case: call runtime. 952 // Slow case: call runtime.
908 __ bind(&slow); 953 __ bind(&slow);
909 Generate(masm, ExternalReference(Runtime::kSetProperty)); 954 GenerateRuntimeSetProperty(masm);
910 } 955 }
911 956
912 957
913 void CallIC::GenerateMiss(MacroAssembler* masm, int argc) { 958 void CallIC::GenerateMiss(MacroAssembler* masm, int argc) {
959 // ----------- S t a t e -------------
960 // rcx : function name
961 // rsp[0] : return address
962 // rsp[8] : argument argc
963 // rsp[16] : argument argc - 1
964 // ...
965 // rsp[argc * 8] : argument 1
966 // rsp[(argc + 1) * 8] : argument 0 = receiver
967 // -----------------------------------
914 // Get the receiver of the function from the stack; 1 ~ return address. 968 // Get the receiver of the function from the stack; 1 ~ return address.
915 __ movq(rdx, Operand(rsp, (argc + 1) * kPointerSize)); 969 __ movq(rdx, Operand(rsp, (argc + 1) * kPointerSize));
916 // Get the name of the function to call from the stack.
917 // 2 ~ receiver, return address.
918 __ movq(rbx, Operand(rsp, (argc + 2) * kPointerSize));
919 970
920 // Enter an internal frame. 971 // Enter an internal frame.
921 __ EnterInternalFrame(); 972 __ EnterInternalFrame();
922 973
923 // Push the receiver and the name of the function. 974 // Push the receiver and the name of the function.
924 __ push(rdx); 975 __ push(rdx);
925 __ push(rbx); 976 __ push(rcx);
926 977
927 // Call the entry. 978 // Call the entry.
928 CEntryStub stub(1); 979 CEntryStub stub(1);
929 __ movq(rax, Immediate(2)); 980 __ movq(rax, Immediate(2));
930 __ movq(rbx, ExternalReference(IC_Utility(kCallIC_Miss))); 981 __ movq(rbx, ExternalReference(IC_Utility(kCallIC_Miss)));
931 __ CallStub(&stub); 982 __ CallStub(&stub);
932 983
933 // Move result to rdi and exit the internal frame. 984 // Move result to rdi and exit the internal frame.
934 __ movq(rdi, rax); 985 __ movq(rdi, rax);
935 __ LeaveInternalFrame(); 986 __ LeaveInternalFrame();
(...skipping 17 matching lines...) Expand all
953 __ bind(&invoke); 1004 __ bind(&invoke);
954 __ InvokeFunction(rdi, actual, JUMP_FUNCTION); 1005 __ InvokeFunction(rdi, actual, JUMP_FUNCTION);
955 } 1006 }
956 1007
957 1008
958 // Defined in ic.cc. 1009 // Defined in ic.cc.
959 Object* CallIC_Miss(Arguments args); 1010 Object* CallIC_Miss(Arguments args);
960 1011
961 void CallIC::GenerateMegamorphic(MacroAssembler* masm, int argc) { 1012 void CallIC::GenerateMegamorphic(MacroAssembler* masm, int argc) {
962 // ----------- S t a t e ------------- 1013 // ----------- S t a t e -------------
963 // rsp[0] return address 1014 // rcx : function name
964 // rsp[8] argument argc 1015 // rsp[0] : return address
965 // rsp[16] argument argc - 1 1016 // rsp[8] : argument argc
1017 // rsp[16] : argument argc - 1
966 // ... 1018 // ...
967 // rsp[argc * 8] argument 1 1019 // rsp[argc * 8] : argument 1
968 // rsp[(argc + 1) * 8] argument 0 = receiver 1020 // rsp[(argc + 1) * 8] : argument 0 = receiver
969 // rsp[(argc + 2) * 8] function name
970 // ----------------------------------- 1021 // -----------------------------------
971 Label number, non_number, non_string, boolean, probe, miss; 1022 Label number, non_number, non_string, boolean, probe, miss;
972 1023
973 // Get the receiver of the function from the stack; 1 ~ return address. 1024 // Get the receiver of the function from the stack; 1 ~ return address.
974 __ movq(rdx, Operand(rsp, (argc + 1) * kPointerSize)); 1025 __ movq(rdx, Operand(rsp, (argc + 1) * kPointerSize));
975 // Get the name of the function from the stack; 2 ~ return address, receiver
976 __ movq(rcx, Operand(rsp, (argc + 2) * kPointerSize));
977 1026
978 // Probe the stub cache. 1027 // Probe the stub cache.
979 Code::Flags flags = 1028 Code::Flags flags =
980 Code::ComputeFlags(Code::CALL_IC, NOT_IN_LOOP, MONOMORPHIC, NORMAL, argc); 1029 Code::ComputeFlags(Code::CALL_IC, NOT_IN_LOOP, MONOMORPHIC, NORMAL, argc);
981 StubCache::GenerateProbe(masm, flags, rdx, rcx, rbx, rax); 1030 StubCache::GenerateProbe(masm, flags, rdx, rcx, rbx, rax);
982 1031
983 // If the stub cache probing failed, the receiver might be a value. 1032 // If the stub cache probing failed, the receiver might be a value.
984 // For value objects, we use the map of the prototype objects for 1033 // For value objects, we use the map of the prototype objects for
985 // the corresponding JSValue for the cache and that is what we need 1034 // the corresponding JSValue for the cache and that is what we need
986 // to probe. 1035 // to probe.
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
1019 // Cache miss: Jump to runtime. 1068 // Cache miss: Jump to runtime.
1020 __ bind(&miss); 1069 __ bind(&miss);
1021 GenerateMiss(masm, argc); 1070 GenerateMiss(masm, argc);
1022 } 1071 }
1023 1072
1024 1073
1025 static void GenerateNormalHelper(MacroAssembler* masm, 1074 static void GenerateNormalHelper(MacroAssembler* masm,
1026 int argc, 1075 int argc,
1027 bool is_global_object, 1076 bool is_global_object,
1028 Label* miss) { 1077 Label* miss) {
1078 // ----------- S t a t e -------------
1079 // rcx : function name
1080 // rdx : receiver
1081 // rsp[0] : return address
1082 // rsp[8] : argument argc
1083 // rsp[16] : argument argc - 1
1084 // ...
1085 // rsp[argc * 8] : argument 1
1086 // rsp[(argc + 1) * 8] : argument 0 = receiver
1087 // -----------------------------------
1029 // Search dictionary - put result in register rdx. 1088 // Search dictionary - put result in register rdx.
1030 GenerateDictionaryLoad(masm, miss, rax, rdx, rbx, rcx, CHECK_DICTIONARY); 1089 GenerateDictionaryLoad(masm, miss, rax, rdx, rbx, rcx, CHECK_DICTIONARY);
1031 1090
1032 // Move the result to register rdi and check that it isn't a smi. 1091 // Move the result to register rdi and check that it isn't a smi.
1033 __ movq(rdi, rdx); 1092 __ movq(rdi, rdx);
1034 __ JumpIfSmi(rdx, miss); 1093 __ JumpIfSmi(rdx, miss);
1035 1094
1036 // Check that the value is a JavaScript function. 1095 // Check that the value is a JavaScript function.
1037 __ CmpObjectType(rdx, JS_FUNCTION_TYPE, rdx); 1096 __ CmpObjectType(rdx, JS_FUNCTION_TYPE, rdx);
1038 __ j(not_equal, miss); 1097 __ j(not_equal, miss);
1039 1098
1040 // Patch the receiver with the global proxy if necessary. 1099 // Patch the receiver with the global proxy if necessary.
1041 if (is_global_object) { 1100 if (is_global_object) {
1042 __ movq(rdx, Operand(rsp, (argc + 1) * kPointerSize)); 1101 __ movq(rdx, Operand(rsp, (argc + 1) * kPointerSize));
1043 __ movq(rdx, FieldOperand(rdx, GlobalObject::kGlobalReceiverOffset)); 1102 __ movq(rdx, FieldOperand(rdx, GlobalObject::kGlobalReceiverOffset));
1044 __ movq(Operand(rsp, (argc + 1) * kPointerSize), rdx); 1103 __ movq(Operand(rsp, (argc + 1) * kPointerSize), rdx);
1045 } 1104 }
1046 1105
1047 // Invoke the function. 1106 // Invoke the function.
1048 ParameterCount actual(argc); 1107 ParameterCount actual(argc);
1049 __ InvokeFunction(rdi, actual, JUMP_FUNCTION); 1108 __ InvokeFunction(rdi, actual, JUMP_FUNCTION);
1050 } 1109 }
1051 1110
1052 1111
1053 void CallIC::GenerateNormal(MacroAssembler* masm, int argc) { 1112 void CallIC::GenerateNormal(MacroAssembler* masm, int argc) {
1054 // ----------- S t a t e ------------- 1113 // ----------- S t a t e -------------
1055 // rsp[0] return address 1114 // rcx : function name
1056 // rsp[8] argument argc 1115 // rsp[0] : return address
1057 // rsp[16] argument argc - 1 1116 // rsp[8] : argument argc
1117 // rsp[16] : argument argc - 1
1058 // ... 1118 // ...
1059 // rsp[argc * 8] argument 1 1119 // rsp[argc * 8] : argument 1
1060 // rsp[(argc + 1) * 8] argument 0 = receiver 1120 // rsp[(argc + 1) * 8] : argument 0 = receiver
1061 // rsp[(argc + 2) * 8] function name
1062 // ----------------------------------- 1121 // -----------------------------------
1063 Label miss, global_object, non_global_object; 1122 Label miss, global_object, non_global_object;
1064 1123
1065 // Get the receiver of the function from the stack. 1124 // Get the receiver of the function from the stack.
1066 __ movq(rdx, Operand(rsp, (argc + 1) * kPointerSize)); 1125 __ movq(rdx, Operand(rsp, (argc + 1) * kPointerSize));
1067 // Get the name of the function from the stack.
1068 __ movq(rcx, Operand(rsp, (argc + 2) * kPointerSize));
1069 1126
1070 // Check that the receiver isn't a smi. 1127 // Check that the receiver isn't a smi.
1071 __ JumpIfSmi(rdx, &miss); 1128 __ JumpIfSmi(rdx, &miss);
1072 1129
1073 // Check that the receiver is a valid JS object. 1130 // Check that the receiver is a valid JS object.
1074 // Because there are so many map checks and type checks, do not 1131 // Because there are so many map checks and type checks, do not
1075 // use CmpObjectType, but load map and type into registers. 1132 // use CmpObjectType, but load map and type into registers.
1076 __ movq(rbx, FieldOperand(rdx, HeapObject::kMapOffset)); 1133 __ movq(rbx, FieldOperand(rdx, HeapObject::kMapOffset));
1077 __ movb(rax, FieldOperand(rbx, Map::kInstanceTypeOffset)); 1134 __ movb(rax, FieldOperand(rbx, Map::kInstanceTypeOffset));
1078 __ cmpb(rax, Immediate(FIRST_JS_OBJECT_TYPE)); 1135 __ cmpb(rax, Immediate(FIRST_JS_OBJECT_TYPE));
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
1125 1182
1126 1183
1127 void LoadIC::ClearInlinedVersion(Address address) { 1184 void LoadIC::ClearInlinedVersion(Address address) {
1128 // Reset the map check of the inlined inobject property load (if 1185 // Reset the map check of the inlined inobject property load (if
1129 // present) to guarantee failure by holding an invalid map (the null 1186 // present) to guarantee failure by holding an invalid map (the null
1130 // value). The offset can be patched to anything. 1187 // value). The offset can be patched to anything.
1131 PatchInlinedLoad(address, Heap::null_value(), kMaxInt); 1188 PatchInlinedLoad(address, Heap::null_value(), kMaxInt);
1132 } 1189 }
1133 1190
1134 1191
1135 void LoadIC::Generate(MacroAssembler* masm, ExternalReference const& f) { 1192 void LoadIC::GenerateMiss(MacroAssembler* masm) {
1136 // ----------- S t a t e ------------- 1193 // ----------- S t a t e -------------
1137 // -- rcx : name 1194 // -- rcx : name
1138 // -- rsp[0] : return address 1195 // -- rsp[0] : return address
1139 // -- rsp[8] : receiver 1196 // -- rsp[8] : receiver
1140 // ----------------------------------- 1197 // -----------------------------------
1141 1198
1142 __ movq(rax, Operand(rsp, kPointerSize));
1143
1144 __ pop(rbx); 1199 __ pop(rbx);
1145 __ push(rax); // receiver 1200 __ push(Operand(rsp, 0)); // receiver
1146 __ push(rcx); // name 1201 __ push(rcx); // name
1147 __ push(rbx); // return address 1202 __ push(rbx); // return address
1148 1203
1149 // Perform tail call to the entry. 1204 // Perform tail call to the entry.
1150 __ TailCallRuntime(f, 2, 1); 1205 __ TailCallRuntime(ExternalReference(IC_Utility(kLoadIC_Miss)), 2, 1);
1151 } 1206 }
1152 1207
1153 1208
1154 void LoadIC::GenerateArrayLength(MacroAssembler* masm) { 1209 void LoadIC::GenerateArrayLength(MacroAssembler* masm) {
1155 // ----------- S t a t e ------------- 1210 // ----------- S t a t e -------------
1156 // -- rcx : name 1211 // -- rcx : name
1157 // -- rsp[0] : return address 1212 // -- rsp[0] : return address
1158 // -- rsp[8] : receiver 1213 // -- rsp[8] : receiver
1159 // ----------------------------------- 1214 // -----------------------------------
1160 Label miss; 1215 Label miss;
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
1196 Code::Flags flags = Code::ComputeFlags(Code::LOAD_IC, 1251 Code::Flags flags = Code::ComputeFlags(Code::LOAD_IC,
1197 NOT_IN_LOOP, 1252 NOT_IN_LOOP,
1198 MONOMORPHIC); 1253 MONOMORPHIC);
1199 StubCache::GenerateProbe(masm, flags, rax, rcx, rbx, rdx); 1254 StubCache::GenerateProbe(masm, flags, rax, rcx, rbx, rdx);
1200 1255
1201 // Cache miss: Jump to runtime. 1256 // Cache miss: Jump to runtime.
1202 StubCompiler::GenerateLoadMiss(masm, Code::LOAD_IC); 1257 StubCompiler::GenerateLoadMiss(masm, Code::LOAD_IC);
1203 } 1258 }
1204 1259
1205 1260
1206 void LoadIC::GenerateMiss(MacroAssembler* masm) {
1207 // ----------- S t a t e -------------
1208 // -- rcx : name
1209 // -- rsp[0] : return address
1210 // -- rsp[8] : receiver
1211 // -----------------------------------
1212
1213 Generate(masm, ExternalReference(IC_Utility(kLoadIC_Miss)));
1214 }
1215
1216
1217 void LoadIC::GenerateNormal(MacroAssembler* masm) { 1261 void LoadIC::GenerateNormal(MacroAssembler* masm) {
1218 // ----------- S t a t e ------------- 1262 // ----------- S t a t e -------------
1219 // -- rcx : name 1263 // -- rcx : name
1220 // -- rsp[0] : return address 1264 // -- rsp[0] : return address
1221 // -- rsp[8] : receiver 1265 // -- rsp[8] : receiver
1222 // ----------------------------------- 1266 // -----------------------------------
1223 Label miss, probe, global; 1267 Label miss, probe, global;
1224 1268
1225 __ movq(rax, Operand(rsp, kPointerSize)); 1269 __ movq(rax, Operand(rsp, kPointerSize));
1226 1270
(...skipping 22 matching lines...) Expand all
1249 __ ret(0); 1293 __ ret(0);
1250 1294
1251 // Global object access: Check access rights. 1295 // Global object access: Check access rights.
1252 __ bind(&global); 1296 __ bind(&global);
1253 __ CheckAccessGlobalProxy(rax, rdx, &miss); 1297 __ CheckAccessGlobalProxy(rax, rdx, &miss);
1254 __ jmp(&probe); 1298 __ jmp(&probe);
1255 1299
1256 // Cache miss: Restore receiver from stack and jump to runtime. 1300 // Cache miss: Restore receiver from stack and jump to runtime.
1257 __ bind(&miss); 1301 __ bind(&miss);
1258 __ movq(rax, Operand(rsp, 1 * kPointerSize)); 1302 __ movq(rax, Operand(rsp, 1 * kPointerSize));
1259 Generate(masm, ExternalReference(IC_Utility(kLoadIC_Miss))); 1303 GenerateMiss(masm);
1260 } 1304 }
1261 1305
1262 1306
1263 void LoadIC::GenerateStringLength(MacroAssembler* masm) { 1307 void LoadIC::GenerateStringLength(MacroAssembler* masm) {
1264 // ----------- S t a t e ------------- 1308 // ----------- S t a t e -------------
1265 // -- rcx : name 1309 // -- rcx : name
1266 // -- rsp[0] : return address 1310 // -- rsp[0] : return address
1267 // -- rsp[8] : receiver 1311 // -- rsp[8] : receiver
1268 // ----------------------------------- 1312 // -----------------------------------
1269 Label miss; 1313 Label miss;
1270 1314
1271 __ movq(rax, Operand(rsp, kPointerSize)); 1315 __ movq(rax, Operand(rsp, kPointerSize));
1272 1316
1273 StubCompiler::GenerateLoadStringLength(masm, rax, rdx, &miss); 1317 StubCompiler::GenerateLoadStringLength(masm, rax, rdx, rbx, &miss);
1274 __ bind(&miss); 1318 __ bind(&miss);
1275 StubCompiler::GenerateLoadMiss(masm, Code::LOAD_IC); 1319 StubCompiler::GenerateLoadMiss(masm, Code::LOAD_IC);
1276 } 1320 }
1277 1321
1278 1322
1279
1280 bool LoadIC::PatchInlinedLoad(Address address, Object* map, int offset) { 1323 bool LoadIC::PatchInlinedLoad(Address address, Object* map, int offset) {
1281 // The address of the instruction following the call. 1324 // The address of the instruction following the call.
1282 Address test_instruction_address = 1325 Address test_instruction_address =
1283 address + Assembler::kCallTargetAddressOffset; 1326 address + Assembler::kCallTargetAddressOffset;
1284 // If the instruction following the call is not a test eax, nothing 1327 // If the instruction following the call is not a test eax, nothing
1285 // was inlined. 1328 // was inlined.
1286 if (*test_instruction_address != kTestEaxByte) return false; 1329 if (*test_instruction_address != kTestEaxByte) return false;
1287 1330
1288 Address delta_address = test_instruction_address + 1; 1331 Address delta_address = test_instruction_address + 1;
1289 // The delta to the start of the map check instruction. 1332 // The delta to the start of the map check instruction.
1290 int delta = *reinterpret_cast<int*>(delta_address); 1333 int delta = *reinterpret_cast<int*>(delta_address);
1291 1334
1292 // The map address is the last 8 bytes of the 10-byte 1335 // The map address is the last 8 bytes of the 10-byte
1293 // immediate move instruction, so we add 2 to get the 1336 // immediate move instruction, so we add 2 to get the
1294 // offset to the last 8 bytes. 1337 // offset to the last 8 bytes.
1295 Address map_address = test_instruction_address + delta + 2; 1338 Address map_address = test_instruction_address + delta + 2;
1296 *(reinterpret_cast<Object**>(map_address)) = map; 1339 *(reinterpret_cast<Object**>(map_address)) = map;
1297 1340
1298 // The offset is in the 32-bit displacement of a seven byte 1341 // The offset is in the 32-bit displacement of a seven byte
1299 // memory-to-register move instruction (REX.W 0x88 ModR/M disp32), 1342 // memory-to-register move instruction (REX.W 0x88 ModR/M disp32),
1300 // so we add 3 to get the offset of the displacement. 1343 // so we add 3 to get the offset of the displacement.
1301 Address offset_address = 1344 Address offset_address =
1302 test_instruction_address + delta + kOffsetToLoadInstruction + 3; 1345 test_instruction_address + delta + kOffsetToLoadInstruction + 3;
1303 *reinterpret_cast<int*>(offset_address) = offset - kHeapObjectTag; 1346 *reinterpret_cast<int*>(offset_address) = offset - kHeapObjectTag;
1304 return true; 1347 return true;
1305 } 1348 }
1306 1349
1350
1307 void StoreIC::GenerateMiss(MacroAssembler* masm) { 1351 void StoreIC::GenerateMiss(MacroAssembler* masm) {
1308 // ----------- S t a t e ------------- 1352 // ----------- S t a t e -------------
1309 // -- rax : value 1353 // -- rax : value
1310 // -- rcx : name 1354 // -- rcx : name
1311 // -- rdx : receiver 1355 // -- rdx : receiver
1312 // -- rsp[0] : return address 1356 // -- rsp[0] : return address
1313 // ----------------------------------- 1357 // -----------------------------------
1314 1358
1315 __ pop(rbx); 1359 __ pop(rbx);
1316 __ push(rdx); // receiver 1360 __ push(rdx); // receiver
1317 __ push(rcx); // name 1361 __ push(rcx); // name
1318 __ push(rax); // value 1362 __ push(rax); // value
1319 __ push(rbx); // return address 1363 __ push(rbx); // return address
1320 1364
1321 // Perform tail call to the entry. 1365 // Perform tail call to the entry.
1322 __ TailCallRuntime(ExternalReference(IC_Utility(kStoreIC_Miss)), 3, 1); 1366 __ TailCallRuntime(ExternalReference(IC_Utility(kStoreIC_Miss)), 3, 1);
1323 } 1367 }
1324 1368
1325 void StoreIC::GenerateExtendStorage(MacroAssembler* masm) {
1326 // ----------- S t a t e -------------
1327 // -- rax : value
1328 // -- rcx : Map (target of map transition)
1329 // -- rdx : receiver
1330 // -- rsp[0] : return address
1331 // -----------------------------------
1332
1333 __ pop(rbx);
1334 __ push(rdx); // receiver
1335 __ push(rcx); // transition map
1336 __ push(rax); // value
1337 __ push(rbx); // return address
1338
1339 // Perform tail call to the entry.
1340 __ TailCallRuntime(
1341 ExternalReference(IC_Utility(kSharedStoreIC_ExtendStorage)), 3, 1);
1342 }
1343 1369
1344 void StoreIC::GenerateMegamorphic(MacroAssembler* masm) { 1370 void StoreIC::GenerateMegamorphic(MacroAssembler* masm) {
1345 // ----------- S t a t e ------------- 1371 // ----------- S t a t e -------------
1346 // -- rax : value 1372 // -- rax : value
1347 // -- rcx : name 1373 // -- rcx : name
1348 // -- rdx : receiver 1374 // -- rdx : receiver
1349 // -- rsp[0] : return address 1375 // -- rsp[0] : return address
1350 // ----------------------------------- 1376 // -----------------------------------
1351 1377
1352 // Get the receiver from the stack and probe the stub cache. 1378 // Get the receiver from the stack and probe the stub cache.
1353 Code::Flags flags = Code::ComputeFlags(Code::STORE_IC, 1379 Code::Flags flags = Code::ComputeFlags(Code::STORE_IC,
1354 NOT_IN_LOOP, 1380 NOT_IN_LOOP,
1355 MONOMORPHIC); 1381 MONOMORPHIC);
1356 StubCache::GenerateProbe(masm, flags, rdx, rcx, rbx, no_reg); 1382 StubCache::GenerateProbe(masm, flags, rdx, rcx, rbx, no_reg);
1357 1383
1358 // Cache miss: Jump to runtime. 1384 // Cache miss: Jump to runtime.
1359 GenerateMiss(masm); 1385 GenerateMiss(masm);
1360 } 1386 }
1361 1387
1388
1389 void StoreIC::GenerateArrayLength(MacroAssembler* masm) {
1390 // ----------- S t a t e -------------
1391 // -- rax : value
1392 // -- rcx : name
1393 // -- rdx : receiver
1394 // -- rsp[0] : return address
1395 // -----------------------------------
1396 //
1397 // This accepts as a receiver anything JSObject::SetElementsLength accepts
1398 // (currently anything except for external and pixel arrays which means
1399 // anything with elements of FixedArray type.), but currently is restricted
1400 // to JSArray.
1401 // Value must be a number, but only smis are accepted as the most common case.
1402
1403 Label miss;
1404
1405 Register receiver = rdx;
1406 Register value = rax;
1407 Register scratch = rbx;
1408
1409 // Check that the receiver isn't a smi.
1410 __ JumpIfSmi(receiver, &miss);
1411
1412 // Check that the object is a JS array.
1413 __ CmpObjectType(receiver, JS_ARRAY_TYPE, scratch);
1414 __ j(not_equal, &miss);
1415
1416 // Check that elements are FixedArray.
1417 __ movq(scratch, FieldOperand(receiver, JSArray::kElementsOffset));
1418 __ CmpObjectType(scratch, FIXED_ARRAY_TYPE, scratch);
1419 __ j(not_equal, &miss);
1420
1421 // Check that value is a smi.
1422 __ JumpIfNotSmi(value, &miss);
1423
1424 // Prepare tail call to StoreIC_ArrayLength.
1425 __ pop(scratch);
1426 __ push(receiver);
1427 __ push(value);
1428 __ push(scratch); // return address
1429
1430 __ TailCallRuntime(ExternalReference(IC_Utility(kStoreIC_ArrayLength)), 2, 1);
1431
1432 __ bind(&miss);
1433
1434 GenerateMiss(masm);
1435 }
1436
1362 1437
1363 #undef __ 1438 #undef __
1364 1439
1365 1440
1366 } } // namespace v8::internal 1441 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/x64/full-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