OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
103 __ jmp(kScratchRegister); | 103 __ jmp(kScratchRegister); |
104 | 104 |
105 __ bind(&miss); | 105 __ bind(&miss); |
106 } | 106 } |
107 | 107 |
108 | 108 |
109 // Helper function used to check that the dictionary doesn't contain | 109 // Helper function used to check that the dictionary doesn't contain |
110 // the property. This function may return false negatives, so miss_label | 110 // the property. This function may return false negatives, so miss_label |
111 // must always call a backup property check that is complete. | 111 // must always call a backup property check that is complete. |
112 // This function is safe to call if the receiver has fast properties. | 112 // This function is safe to call if the receiver has fast properties. |
113 // Name must be an internalized string and receiver must be a heap object. | 113 // Name must be unique and receiver must be a heap object. |
114 static void GenerateDictionaryNegativeLookup(MacroAssembler* masm, | 114 static void GenerateDictionaryNegativeLookup(MacroAssembler* masm, |
115 Label* miss_label, | 115 Label* miss_label, |
116 Register receiver, | 116 Register receiver, |
117 Handle<String> name, | 117 Handle<Name> name, |
118 Register r0, | 118 Register r0, |
119 Register r1) { | 119 Register r1) { |
120 ASSERT(name->IsInternalizedString()); | 120 ASSERT(name->IsUniqueName()); |
121 Counters* counters = masm->isolate()->counters(); | 121 Counters* counters = masm->isolate()->counters(); |
122 __ IncrementCounter(counters->negative_lookups(), 1); | 122 __ IncrementCounter(counters->negative_lookups(), 1); |
123 __ IncrementCounter(counters->negative_lookups_miss(), 1); | 123 __ IncrementCounter(counters->negative_lookups_miss(), 1); |
124 | 124 |
125 __ movq(r0, FieldOperand(receiver, HeapObject::kMapOffset)); | 125 __ movq(r0, FieldOperand(receiver, HeapObject::kMapOffset)); |
126 | 126 |
127 const int kInterceptorOrAccessCheckNeededMask = | 127 const int kInterceptorOrAccessCheckNeededMask = |
128 (1 << Map::kHasNamedInterceptor) | (1 << Map::kIsAccessCheckNeeded); | 128 (1 << Map::kHasNamedInterceptor) | (1 << Map::kIsAccessCheckNeeded); |
129 | 129 |
130 // Bail out if the receiver has a named interceptor or requires access checks. | 130 // Bail out if the receiver has a named interceptor or requires access checks. |
131 __ testb(FieldOperand(r0, Map::kBitFieldOffset), | 131 __ testb(FieldOperand(r0, Map::kBitFieldOffset), |
132 Immediate(kInterceptorOrAccessCheckNeededMask)); | 132 Immediate(kInterceptorOrAccessCheckNeededMask)); |
133 __ j(not_zero, miss_label); | 133 __ j(not_zero, miss_label); |
134 | 134 |
135 // Check that receiver is a JSObject. | 135 // Check that receiver is a JSObject. |
136 __ CmpInstanceType(r0, FIRST_SPEC_OBJECT_TYPE); | 136 __ CmpInstanceType(r0, FIRST_SPEC_OBJECT_TYPE); |
137 __ j(below, miss_label); | 137 __ j(below, miss_label); |
138 | 138 |
139 // Load properties array. | 139 // Load properties array. |
140 Register properties = r0; | 140 Register properties = r0; |
141 __ movq(properties, FieldOperand(receiver, JSObject::kPropertiesOffset)); | 141 __ movq(properties, FieldOperand(receiver, JSObject::kPropertiesOffset)); |
142 | 142 |
143 // Check that the properties array is a dictionary. | 143 // Check that the properties array is a dictionary. |
144 __ CompareRoot(FieldOperand(properties, HeapObject::kMapOffset), | 144 __ CompareRoot(FieldOperand(properties, HeapObject::kMapOffset), |
145 Heap::kHashTableMapRootIndex); | 145 Heap::kHashTableMapRootIndex); |
146 __ j(not_equal, miss_label); | 146 __ j(not_equal, miss_label); |
147 | 147 |
148 Label done; | 148 Label done; |
149 StringDictionaryLookupStub::GenerateNegativeLookup(masm, | 149 NameDictionaryLookupStub::GenerateNegativeLookup(masm, |
150 miss_label, | 150 miss_label, |
151 &done, | 151 &done, |
152 properties, | 152 properties, |
153 name, | 153 name, |
154 r1); | 154 r1); |
155 __ bind(&done); | 155 __ bind(&done); |
156 __ DecrementCounter(counters->negative_lookups_miss(), 1); | 156 __ DecrementCounter(counters->negative_lookups_miss(), 1); |
157 } | 157 } |
158 | 158 |
159 | 159 |
160 void StubCache::GenerateProbe(MacroAssembler* masm, | 160 void StubCache::GenerateProbe(MacroAssembler* masm, |
161 Code::Flags flags, | 161 Code::Flags flags, |
162 Register receiver, | 162 Register receiver, |
163 Register name, | 163 Register name, |
164 Register scratch, | 164 Register scratch, |
(...skipping 21 matching lines...) Expand all Loading... |
186 ASSERT(extra2.is(no_reg)); | 186 ASSERT(extra2.is(no_reg)); |
187 ASSERT(extra3.is(no_reg)); | 187 ASSERT(extra3.is(no_reg)); |
188 | 188 |
189 Counters* counters = masm->isolate()->counters(); | 189 Counters* counters = masm->isolate()->counters(); |
190 __ IncrementCounter(counters->megamorphic_stub_cache_probes(), 1); | 190 __ IncrementCounter(counters->megamorphic_stub_cache_probes(), 1); |
191 | 191 |
192 // Check that the receiver isn't a smi. | 192 // Check that the receiver isn't a smi. |
193 __ JumpIfSmi(receiver, &miss); | 193 __ JumpIfSmi(receiver, &miss); |
194 | 194 |
195 // Get the map of the receiver and compute the hash. | 195 // Get the map of the receiver and compute the hash. |
196 __ movl(scratch, FieldOperand(name, String::kHashFieldOffset)); | 196 __ movl(scratch, FieldOperand(name, Name::kHashFieldOffset)); |
197 // Use only the low 32 bits of the map pointer. | 197 // Use only the low 32 bits of the map pointer. |
198 __ addl(scratch, FieldOperand(receiver, HeapObject::kMapOffset)); | 198 __ addl(scratch, FieldOperand(receiver, HeapObject::kMapOffset)); |
199 __ xor_(scratch, Immediate(flags)); | 199 __ xor_(scratch, Immediate(flags)); |
200 // We mask out the last two bits because they are not part of the hash and | 200 // We mask out the last two bits because they are not part of the hash and |
201 // they are always 01 for maps. Also in the two 'and' instructions below. | 201 // they are always 01 for maps. Also in the two 'and' instructions below. |
202 __ and_(scratch, Immediate((kPrimaryTableSize - 1) << kHeapObjectTagSize)); | 202 __ and_(scratch, Immediate((kPrimaryTableSize - 1) << kHeapObjectTagSize)); |
203 | 203 |
204 // Probe the primary table. | 204 // Probe the primary table. |
205 ProbeTable(isolate, masm, flags, kPrimary, receiver, name, scratch); | 205 ProbeTable(isolate, masm, flags, kPrimary, receiver, name, scratch); |
206 | 206 |
207 // Primary miss: Compute hash for secondary probe. | 207 // Primary miss: Compute hash for secondary probe. |
208 __ movl(scratch, FieldOperand(name, String::kHashFieldOffset)); | 208 __ movl(scratch, FieldOperand(name, Name::kHashFieldOffset)); |
209 __ addl(scratch, FieldOperand(receiver, HeapObject::kMapOffset)); | 209 __ addl(scratch, FieldOperand(receiver, HeapObject::kMapOffset)); |
210 __ xor_(scratch, Immediate(flags)); | 210 __ xor_(scratch, Immediate(flags)); |
211 __ and_(scratch, Immediate((kPrimaryTableSize - 1) << kHeapObjectTagSize)); | 211 __ and_(scratch, Immediate((kPrimaryTableSize - 1) << kHeapObjectTagSize)); |
212 __ subl(scratch, name); | 212 __ subl(scratch, name); |
213 __ addl(scratch, Immediate(flags)); | 213 __ addl(scratch, Immediate(flags)); |
214 __ and_(scratch, Immediate((kSecondaryTableSize - 1) << kHeapObjectTagSize)); | 214 __ and_(scratch, Immediate((kSecondaryTableSize - 1) << kHeapObjectTagSize)); |
215 | 215 |
216 // Probe the secondary table. | 216 // Probe the secondary table. |
217 ProbeTable(isolate, masm, flags, kSecondary, receiver, name, scratch); | 217 ProbeTable(isolate, masm, flags, kSecondary, receiver, name, scratch); |
218 | 218 |
(...skipping 306 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
525 Register name, | 525 Register name, |
526 Code::ExtraICState extra_ic_state) | 526 Code::ExtraICState extra_ic_state) |
527 : stub_compiler_(stub_compiler), | 527 : stub_compiler_(stub_compiler), |
528 arguments_(arguments), | 528 arguments_(arguments), |
529 name_(name), | 529 name_(name), |
530 extra_ic_state_(extra_ic_state) {} | 530 extra_ic_state_(extra_ic_state) {} |
531 | 531 |
532 void Compile(MacroAssembler* masm, | 532 void Compile(MacroAssembler* masm, |
533 Handle<JSObject> object, | 533 Handle<JSObject> object, |
534 Handle<JSObject> holder, | 534 Handle<JSObject> holder, |
535 Handle<String> name, | 535 Handle<Name> name, |
536 LookupResult* lookup, | 536 LookupResult* lookup, |
537 Register receiver, | 537 Register receiver, |
538 Register scratch1, | 538 Register scratch1, |
539 Register scratch2, | 539 Register scratch2, |
540 Register scratch3, | 540 Register scratch3, |
541 Label* miss) { | 541 Label* miss) { |
542 ASSERT(holder->HasNamedInterceptor()); | 542 ASSERT(holder->HasNamedInterceptor()); |
543 ASSERT(!holder->GetNamedInterceptor()->getter()->IsUndefined()); | 543 ASSERT(!holder->GetNamedInterceptor()->getter()->IsUndefined()); |
544 | 544 |
545 // Check that the receiver isn't a smi. | 545 // Check that the receiver isn't a smi. |
(...skipping 11 matching lines...) Expand all Loading... |
557 | 557 |
558 private: | 558 private: |
559 void CompileCacheable(MacroAssembler* masm, | 559 void CompileCacheable(MacroAssembler* masm, |
560 Handle<JSObject> object, | 560 Handle<JSObject> object, |
561 Register receiver, | 561 Register receiver, |
562 Register scratch1, | 562 Register scratch1, |
563 Register scratch2, | 563 Register scratch2, |
564 Register scratch3, | 564 Register scratch3, |
565 Handle<JSObject> interceptor_holder, | 565 Handle<JSObject> interceptor_holder, |
566 LookupResult* lookup, | 566 LookupResult* lookup, |
567 Handle<String> name, | 567 Handle<Name> name, |
568 const CallOptimization& optimization, | 568 const CallOptimization& optimization, |
569 Label* miss_label) { | 569 Label* miss_label) { |
570 ASSERT(optimization.is_constant_call()); | 570 ASSERT(optimization.is_constant_call()); |
571 ASSERT(!lookup->holder()->IsGlobalObject()); | 571 ASSERT(!lookup->holder()->IsGlobalObject()); |
572 | 572 |
573 int depth1 = kInvalidProtoDepth; | 573 int depth1 = kInvalidProtoDepth; |
574 int depth2 = kInvalidProtoDepth; | 574 int depth2 = kInvalidProtoDepth; |
575 bool can_do_fast_api_call = false; | 575 bool can_do_fast_api_call = false; |
576 if (optimization.is_simple_api_call() && | 576 if (optimization.is_simple_api_call() && |
577 !lookup->holder()->IsGlobalObject()) { | 577 !lookup->holder()->IsGlobalObject()) { |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
650 FreeSpaceForFastApiCall(masm, scratch1); | 650 FreeSpaceForFastApiCall(masm, scratch1); |
651 } | 651 } |
652 } | 652 } |
653 | 653 |
654 void CompileRegular(MacroAssembler* masm, | 654 void CompileRegular(MacroAssembler* masm, |
655 Handle<JSObject> object, | 655 Handle<JSObject> object, |
656 Register receiver, | 656 Register receiver, |
657 Register scratch1, | 657 Register scratch1, |
658 Register scratch2, | 658 Register scratch2, |
659 Register scratch3, | 659 Register scratch3, |
660 Handle<String> name, | 660 Handle<Name> name, |
661 Handle<JSObject> interceptor_holder, | 661 Handle<JSObject> interceptor_holder, |
662 Label* miss_label) { | 662 Label* miss_label) { |
663 Register holder = | 663 Register holder = |
664 stub_compiler_->CheckPrototypes(object, receiver, interceptor_holder, | 664 stub_compiler_->CheckPrototypes(object, receiver, interceptor_holder, |
665 scratch1, scratch2, scratch3, | 665 scratch1, scratch2, scratch3, |
666 name, miss_label); | 666 name, miss_label); |
667 | 667 |
668 FrameScope scope(masm, StackFrame::INTERNAL); | 668 FrameScope scope(masm, StackFrame::INTERNAL); |
669 // Save the name_ register across the call. | 669 // Save the name_ register across the call. |
670 __ push(name_); | 670 __ push(name_); |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
738 __ Jump(code, RelocInfo::CODE_TARGET); | 738 __ Jump(code, RelocInfo::CODE_TARGET); |
739 } | 739 } |
740 | 740 |
741 | 741 |
742 // Both name_reg and receiver_reg are preserved on jumps to miss_label, | 742 // Both name_reg and receiver_reg are preserved on jumps to miss_label, |
743 // but may be destroyed if store is successful. | 743 // but may be destroyed if store is successful. |
744 void StubCompiler::GenerateStoreField(MacroAssembler* masm, | 744 void StubCompiler::GenerateStoreField(MacroAssembler* masm, |
745 Handle<JSObject> object, | 745 Handle<JSObject> object, |
746 int index, | 746 int index, |
747 Handle<Map> transition, | 747 Handle<Map> transition, |
748 Handle<String> name, | 748 Handle<Name> name, |
749 Register receiver_reg, | 749 Register receiver_reg, |
750 Register name_reg, | 750 Register name_reg, |
751 Register scratch1, | 751 Register scratch1, |
752 Register scratch2, | 752 Register scratch2, |
753 Label* miss_label) { | 753 Label* miss_label) { |
754 LookupResult lookup(masm->isolate()); | 754 LookupResult lookup(masm->isolate()); |
755 object->Lookup(*name, &lookup); | 755 object->Lookup(*name, &lookup); |
756 if (lookup.IsFound() && (lookup.IsReadOnly() || !lookup.IsCacheable())) { | 756 if (lookup.IsFound() && (lookup.IsReadOnly() || !lookup.IsCacheable())) { |
757 // In sloppy mode, we could just return the value and be done. However, we | 757 // In sloppy mode, we could just return the value and be done. However, we |
758 // might be in strict mode, where we have to throw. Since we cannot tell, | 758 // might be in strict mode, where we have to throw. Since we cannot tell, |
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
866 // Return the value (register rax). | 866 // Return the value (register rax). |
867 __ ret(0); | 867 __ ret(0); |
868 } | 868 } |
869 | 869 |
870 | 870 |
871 // Generate code to check that a global property cell is empty. Create | 871 // Generate code to check that a global property cell is empty. Create |
872 // the property cell at compilation time if no cell exists for the | 872 // the property cell at compilation time if no cell exists for the |
873 // property. | 873 // property. |
874 static void GenerateCheckPropertyCell(MacroAssembler* masm, | 874 static void GenerateCheckPropertyCell(MacroAssembler* masm, |
875 Handle<GlobalObject> global, | 875 Handle<GlobalObject> global, |
876 Handle<String> name, | 876 Handle<Name> name, |
877 Register scratch, | 877 Register scratch, |
878 Label* miss) { | 878 Label* miss) { |
879 Handle<JSGlobalPropertyCell> cell = | 879 Handle<JSGlobalPropertyCell> cell = |
880 GlobalObject::EnsurePropertyCell(global, name); | 880 GlobalObject::EnsurePropertyCell(global, name); |
881 ASSERT(cell->value()->IsTheHole()); | 881 ASSERT(cell->value()->IsTheHole()); |
882 __ Move(scratch, cell); | 882 __ Move(scratch, cell); |
883 __ Cmp(FieldOperand(scratch, JSGlobalPropertyCell::kValueOffset), | 883 __ Cmp(FieldOperand(scratch, JSGlobalPropertyCell::kValueOffset), |
884 masm->isolate()->factory()->the_hole_value()); | 884 masm->isolate()->factory()->the_hole_value()); |
885 __ j(not_equal, miss); | 885 __ j(not_equal, miss); |
886 } | 886 } |
887 | 887 |
888 | 888 |
889 // Calls GenerateCheckPropertyCell for each global object in the prototype chain | 889 // Calls GenerateCheckPropertyCell for each global object in the prototype chain |
890 // from object to (but not including) holder. | 890 // from object to (but not including) holder. |
891 static void GenerateCheckPropertyCells(MacroAssembler* masm, | 891 static void GenerateCheckPropertyCells(MacroAssembler* masm, |
892 Handle<JSObject> object, | 892 Handle<JSObject> object, |
893 Handle<JSObject> holder, | 893 Handle<JSObject> holder, |
894 Handle<String> name, | 894 Handle<Name> name, |
895 Register scratch, | 895 Register scratch, |
896 Label* miss) { | 896 Label* miss) { |
897 Handle<JSObject> current = object; | 897 Handle<JSObject> current = object; |
898 while (!current.is_identical_to(holder)) { | 898 while (!current.is_identical_to(holder)) { |
899 if (current->IsGlobalObject()) { | 899 if (current->IsGlobalObject()) { |
900 GenerateCheckPropertyCell(masm, | 900 GenerateCheckPropertyCell(masm, |
901 Handle<GlobalObject>::cast(current), | 901 Handle<GlobalObject>::cast(current), |
902 name, | 902 name, |
903 scratch, | 903 scratch, |
904 miss); | 904 miss); |
905 } | 905 } |
906 current = Handle<JSObject>(JSObject::cast(current->GetPrototype())); | 906 current = Handle<JSObject>(JSObject::cast(current->GetPrototype())); |
907 } | 907 } |
908 } | 908 } |
909 | 909 |
910 #undef __ | 910 #undef __ |
911 #define __ ACCESS_MASM((masm())) | 911 #define __ ACCESS_MASM((masm())) |
912 | 912 |
913 | 913 |
914 Register StubCompiler::CheckPrototypes(Handle<JSObject> object, | 914 Register StubCompiler::CheckPrototypes(Handle<JSObject> object, |
915 Register object_reg, | 915 Register object_reg, |
916 Handle<JSObject> holder, | 916 Handle<JSObject> holder, |
917 Register holder_reg, | 917 Register holder_reg, |
918 Register scratch1, | 918 Register scratch1, |
919 Register scratch2, | 919 Register scratch2, |
920 Handle<String> name, | 920 Handle<Name> name, |
921 int save_at_depth, | 921 int save_at_depth, |
922 Label* miss) { | 922 Label* miss) { |
923 // Make sure there's no overlap between holder and object registers. | 923 // Make sure there's no overlap between holder and object registers. |
924 ASSERT(!scratch1.is(object_reg) && !scratch1.is(holder_reg)); | 924 ASSERT(!scratch1.is(object_reg) && !scratch1.is(holder_reg)); |
925 ASSERT(!scratch2.is(object_reg) && !scratch2.is(holder_reg) | 925 ASSERT(!scratch2.is(object_reg) && !scratch2.is(holder_reg) |
926 && !scratch2.is(scratch1)); | 926 && !scratch2.is(scratch1)); |
927 | 927 |
928 // Keep track of the current object in register reg. On the first | 928 // Keep track of the current object in register reg. On the first |
929 // iteration, reg is an alias for object_reg, on later iterations, | 929 // iteration, reg is an alias for object_reg, on later iterations, |
930 // it is an alias for holder_reg. | 930 // it is an alias for holder_reg. |
(...skipping 11 matching lines...) Expand all Loading... |
942 ++depth; | 942 ++depth; |
943 | 943 |
944 // Only global objects and objects that do not require access | 944 // Only global objects and objects that do not require access |
945 // checks are allowed in stubs. | 945 // checks are allowed in stubs. |
946 ASSERT(current->IsJSGlobalProxy() || !current->IsAccessCheckNeeded()); | 946 ASSERT(current->IsJSGlobalProxy() || !current->IsAccessCheckNeeded()); |
947 | 947 |
948 Handle<JSObject> prototype(JSObject::cast(current->GetPrototype())); | 948 Handle<JSObject> prototype(JSObject::cast(current->GetPrototype())); |
949 if (!current->HasFastProperties() && | 949 if (!current->HasFastProperties() && |
950 !current->IsJSGlobalObject() && | 950 !current->IsJSGlobalObject() && |
951 !current->IsJSGlobalProxy()) { | 951 !current->IsJSGlobalProxy()) { |
952 if (!name->IsInternalizedString()) { | 952 if (!name->IsUniqueName()) { |
953 name = factory()->InternalizeString(name); | 953 ASSERT(name->IsString()); |
| 954 name = factory()->InternalizeString(Handle<String>::cast(name)); |
954 } | 955 } |
955 ASSERT(current->property_dictionary()->FindEntry(*name) == | 956 ASSERT(current->property_dictionary()->FindEntry(*name) == |
956 StringDictionary::kNotFound); | 957 NameDictionary::kNotFound); |
957 | 958 |
958 GenerateDictionaryNegativeLookup(masm(), miss, reg, name, | 959 GenerateDictionaryNegativeLookup(masm(), miss, reg, name, |
959 scratch1, scratch2); | 960 scratch1, scratch2); |
960 | 961 |
961 __ movq(scratch1, FieldOperand(reg, HeapObject::kMapOffset)); | 962 __ movq(scratch1, FieldOperand(reg, HeapObject::kMapOffset)); |
962 reg = holder_reg; // From now on the object will be in holder_reg. | 963 reg = holder_reg; // From now on the object will be in holder_reg. |
963 __ movq(reg, FieldOperand(scratch1, Map::kPrototypeOffset)); | 964 __ movq(reg, FieldOperand(scratch1, Map::kPrototypeOffset)); |
964 } else { | 965 } else { |
965 bool in_new_space = heap()->InNewSpace(*prototype); | 966 bool in_new_space = heap()->InNewSpace(*prototype); |
966 Handle<Map> current_map(current->map()); | 967 Handle<Map> current_map(current->map()); |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1021 } | 1022 } |
1022 | 1023 |
1023 | 1024 |
1024 void StubCompiler::GenerateLoadField(Handle<JSObject> object, | 1025 void StubCompiler::GenerateLoadField(Handle<JSObject> object, |
1025 Handle<JSObject> holder, | 1026 Handle<JSObject> holder, |
1026 Register receiver, | 1027 Register receiver, |
1027 Register scratch1, | 1028 Register scratch1, |
1028 Register scratch2, | 1029 Register scratch2, |
1029 Register scratch3, | 1030 Register scratch3, |
1030 PropertyIndex index, | 1031 PropertyIndex index, |
1031 Handle<String> name, | 1032 Handle<Name> name, |
1032 Label* miss) { | 1033 Label* miss) { |
1033 // Check that the receiver isn't a smi. | 1034 // Check that the receiver isn't a smi. |
1034 __ JumpIfSmi(receiver, miss); | 1035 __ JumpIfSmi(receiver, miss); |
1035 | 1036 |
1036 // Check the prototype chain. | 1037 // Check the prototype chain. |
1037 Register reg = CheckPrototypes( | 1038 Register reg = CheckPrototypes( |
1038 object, receiver, holder, scratch1, scratch2, scratch3, name, miss); | 1039 object, receiver, holder, scratch1, scratch2, scratch3, name, miss); |
1039 | 1040 |
1040 // Get the value from the properties. | 1041 // Get the value from the properties. |
1041 GenerateFastPropertyLoad(masm(), rax, reg, holder, index); | 1042 GenerateFastPropertyLoad(masm(), rax, reg, holder, index); |
1042 __ ret(0); | 1043 __ ret(0); |
1043 } | 1044 } |
1044 | 1045 |
1045 | 1046 |
1046 void StubCompiler::GenerateDictionaryLoadCallback(Register receiver, | 1047 void StubCompiler::GenerateDictionaryLoadCallback(Register receiver, |
1047 Register name_reg, | 1048 Register name_reg, |
1048 Register scratch1, | 1049 Register scratch1, |
1049 Register scratch2, | 1050 Register scratch2, |
1050 Register scratch3, | 1051 Register scratch3, |
1051 Handle<AccessorInfo> callback, | 1052 Handle<AccessorInfo> callback, |
1052 Handle<String> name, | 1053 Handle<Name> name, |
1053 Label* miss) { | 1054 Label* miss) { |
1054 ASSERT(!receiver.is(scratch1)); | 1055 ASSERT(!receiver.is(scratch1)); |
1055 ASSERT(!receiver.is(scratch2)); | 1056 ASSERT(!receiver.is(scratch2)); |
1056 ASSERT(!receiver.is(scratch3)); | 1057 ASSERT(!receiver.is(scratch3)); |
1057 | 1058 |
1058 // Load the properties dictionary. | 1059 // Load the properties dictionary. |
1059 Register dictionary = scratch1; | 1060 Register dictionary = scratch1; |
1060 __ movq(dictionary, FieldOperand(receiver, JSObject::kPropertiesOffset)); | 1061 __ movq(dictionary, FieldOperand(receiver, JSObject::kPropertiesOffset)); |
1061 | 1062 |
1062 // Probe the dictionary. | 1063 // Probe the dictionary. |
1063 Label probe_done; | 1064 Label probe_done; |
1064 StringDictionaryLookupStub::GeneratePositiveLookup(masm(), | 1065 NameDictionaryLookupStub::GeneratePositiveLookup(masm(), |
1065 miss, | 1066 miss, |
1066 &probe_done, | 1067 &probe_done, |
1067 dictionary, | 1068 dictionary, |
1068 name_reg, | 1069 name_reg, |
1069 scratch2, | 1070 scratch2, |
1070 scratch3); | 1071 scratch3); |
1071 __ bind(&probe_done); | 1072 __ bind(&probe_done); |
1072 | 1073 |
1073 // If probing finds an entry in the dictionary, scratch3 contains the | 1074 // If probing finds an entry in the dictionary, scratch3 contains the |
1074 // index into the dictionary. Check that the value is the callback. | 1075 // index into the dictionary. Check that the value is the callback. |
1075 Register index = scratch3; | 1076 Register index = scratch3; |
1076 const int kElementsStartOffset = | 1077 const int kElementsStartOffset = |
1077 StringDictionary::kHeaderSize + | 1078 NameDictionary::kHeaderSize + |
1078 StringDictionary::kElementsStartIndex * kPointerSize; | 1079 NameDictionary::kElementsStartIndex * kPointerSize; |
1079 const int kValueOffset = kElementsStartOffset + kPointerSize; | 1080 const int kValueOffset = kElementsStartOffset + kPointerSize; |
1080 __ movq(scratch2, | 1081 __ movq(scratch2, |
1081 Operand(dictionary, index, times_pointer_size, | 1082 Operand(dictionary, index, times_pointer_size, |
1082 kValueOffset - kHeapObjectTag)); | 1083 kValueOffset - kHeapObjectTag)); |
1083 __ movq(scratch3, callback, RelocInfo::EMBEDDED_OBJECT); | 1084 __ movq(scratch3, callback, RelocInfo::EMBEDDED_OBJECT); |
1084 __ cmpq(scratch2, scratch3); | 1085 __ cmpq(scratch2, scratch3); |
1085 __ j(not_equal, miss); | 1086 __ j(not_equal, miss); |
1086 } | 1087 } |
1087 | 1088 |
1088 | 1089 |
1089 void StubCompiler::GenerateLoadCallback(Handle<JSObject> object, | 1090 void StubCompiler::GenerateLoadCallback(Handle<JSObject> object, |
1090 Handle<JSObject> holder, | 1091 Handle<JSObject> holder, |
1091 Register receiver, | 1092 Register receiver, |
1092 Register name_reg, | 1093 Register name_reg, |
1093 Register scratch1, | 1094 Register scratch1, |
1094 Register scratch2, | 1095 Register scratch2, |
1095 Register scratch3, | 1096 Register scratch3, |
1096 Register scratch4, | 1097 Register scratch4, |
1097 Handle<AccessorInfo> callback, | 1098 Handle<AccessorInfo> callback, |
1098 Handle<String> name, | 1099 Handle<Name> name, |
1099 Label* miss) { | 1100 Label* miss) { |
1100 // Check that the receiver isn't a smi. | 1101 // Check that the receiver isn't a smi. |
1101 __ JumpIfSmi(receiver, miss); | 1102 __ JumpIfSmi(receiver, miss); |
1102 | 1103 |
1103 // Check that the maps haven't changed. | 1104 // Check that the maps haven't changed. |
1104 Register reg = CheckPrototypes(object, receiver, holder, scratch1, | 1105 Register reg = CheckPrototypes(object, receiver, holder, scratch1, |
1105 scratch2, scratch3, name, miss); | 1106 scratch2, scratch3, name, miss); |
1106 | 1107 |
1107 if (!holder->HasFastProperties() && !holder->IsJSGlobalObject()) { | 1108 if (!holder->HasFastProperties() && !holder->IsJSGlobalObject()) { |
1108 GenerateDictionaryLoadCallback( | 1109 GenerateDictionaryLoadCallback( |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1163 } | 1164 } |
1164 | 1165 |
1165 | 1166 |
1166 void StubCompiler::GenerateLoadConstant(Handle<JSObject> object, | 1167 void StubCompiler::GenerateLoadConstant(Handle<JSObject> object, |
1167 Handle<JSObject> holder, | 1168 Handle<JSObject> holder, |
1168 Register receiver, | 1169 Register receiver, |
1169 Register scratch1, | 1170 Register scratch1, |
1170 Register scratch2, | 1171 Register scratch2, |
1171 Register scratch3, | 1172 Register scratch3, |
1172 Handle<JSFunction> value, | 1173 Handle<JSFunction> value, |
1173 Handle<String> name, | 1174 Handle<Name> name, |
1174 Label* miss) { | 1175 Label* miss) { |
1175 // Check that the receiver isn't a smi. | 1176 // Check that the receiver isn't a smi. |
1176 __ JumpIfSmi(receiver, miss); | 1177 __ JumpIfSmi(receiver, miss); |
1177 | 1178 |
1178 // Check that the maps haven't changed. | 1179 // Check that the maps haven't changed. |
1179 CheckPrototypes( | 1180 CheckPrototypes( |
1180 object, receiver, holder, scratch1, scratch2, scratch3, name, miss); | 1181 object, receiver, holder, scratch1, scratch2, scratch3, name, miss); |
1181 | 1182 |
1182 // Return the constant value. | 1183 // Return the constant value. |
1183 __ LoadHeapObject(rax, value); | 1184 __ LoadHeapObject(rax, value); |
1184 __ ret(0); | 1185 __ ret(0); |
1185 } | 1186 } |
1186 | 1187 |
1187 | 1188 |
1188 void StubCompiler::GenerateLoadInterceptor(Handle<JSObject> object, | 1189 void StubCompiler::GenerateLoadInterceptor(Handle<JSObject> object, |
1189 Handle<JSObject> interceptor_holder, | 1190 Handle<JSObject> interceptor_holder, |
1190 LookupResult* lookup, | 1191 LookupResult* lookup, |
1191 Register receiver, | 1192 Register receiver, |
1192 Register name_reg, | 1193 Register name_reg, |
1193 Register scratch1, | 1194 Register scratch1, |
1194 Register scratch2, | 1195 Register scratch2, |
1195 Register scratch3, | 1196 Register scratch3, |
1196 Handle<String> name, | 1197 Handle<Name> name, |
1197 Label* miss) { | 1198 Label* miss) { |
1198 ASSERT(interceptor_holder->HasNamedInterceptor()); | 1199 ASSERT(interceptor_holder->HasNamedInterceptor()); |
1199 ASSERT(!interceptor_holder->GetNamedInterceptor()->getter()->IsUndefined()); | 1200 ASSERT(!interceptor_holder->GetNamedInterceptor()->getter()->IsUndefined()); |
1200 | 1201 |
1201 // Check that the receiver isn't a smi. | 1202 // Check that the receiver isn't a smi. |
1202 __ JumpIfSmi(receiver, miss); | 1203 __ JumpIfSmi(receiver, miss); |
1203 | 1204 |
1204 // So far the most popular follow ups for interceptor loads are FIELD | 1205 // So far the most popular follow ups for interceptor loads are FIELD |
1205 // and CALLBACKS, so inline only them, other cases may be added | 1206 // and CALLBACKS, so inline only them, other cases may be added |
1206 // later. | 1207 // later. |
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1328 name_reg, interceptor_holder); | 1329 name_reg, interceptor_holder); |
1329 __ push(scratch2); // restore old return address | 1330 __ push(scratch2); // restore old return address |
1330 | 1331 |
1331 ExternalReference ref = ExternalReference( | 1332 ExternalReference ref = ExternalReference( |
1332 IC_Utility(IC::kLoadPropertyWithInterceptorForLoad), isolate()); | 1333 IC_Utility(IC::kLoadPropertyWithInterceptorForLoad), isolate()); |
1333 __ TailCallExternalReference(ref, 6, 1); | 1334 __ TailCallExternalReference(ref, 6, 1); |
1334 } | 1335 } |
1335 } | 1336 } |
1336 | 1337 |
1337 | 1338 |
1338 void CallStubCompiler::GenerateNameCheck(Handle<String> name, Label* miss) { | 1339 void CallStubCompiler::GenerateNameCheck(Handle<Name> name, Label* miss) { |
1339 if (kind_ == Code::KEYED_CALL_IC) { | 1340 if (kind_ == Code::KEYED_CALL_IC) { |
1340 __ Cmp(rcx, name); | 1341 __ Cmp(rcx, name); |
1341 __ j(not_equal, miss); | 1342 __ j(not_equal, miss); |
1342 } | 1343 } |
1343 } | 1344 } |
1344 | 1345 |
1345 | 1346 |
1346 void CallStubCompiler::GenerateGlobalReceiverCheck(Handle<JSObject> object, | 1347 void CallStubCompiler::GenerateGlobalReceiverCheck(Handle<JSObject> object, |
1347 Handle<JSObject> holder, | 1348 Handle<JSObject> holder, |
1348 Handle<String> name, | 1349 Handle<Name> name, |
1349 Label* miss) { | 1350 Label* miss) { |
1350 ASSERT(holder->IsGlobalObject()); | 1351 ASSERT(holder->IsGlobalObject()); |
1351 | 1352 |
1352 // Get the number of arguments. | 1353 // Get the number of arguments. |
1353 const int argc = arguments().immediate(); | 1354 const int argc = arguments().immediate(); |
1354 | 1355 |
1355 // Get the receiver from the stack. | 1356 // Get the receiver from the stack. |
1356 __ movq(rdx, Operand(rsp, (argc + 1) * kPointerSize)); | 1357 __ movq(rdx, Operand(rsp, (argc + 1) * kPointerSize)); |
1357 | 1358 |
1358 | 1359 |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1396 isolate()->stub_cache()->ComputeCallMiss(arguments().immediate(), | 1397 isolate()->stub_cache()->ComputeCallMiss(arguments().immediate(), |
1397 kind_, | 1398 kind_, |
1398 extra_state_); | 1399 extra_state_); |
1399 __ Jump(code, RelocInfo::CODE_TARGET); | 1400 __ Jump(code, RelocInfo::CODE_TARGET); |
1400 } | 1401 } |
1401 | 1402 |
1402 | 1403 |
1403 Handle<Code> CallStubCompiler::CompileCallField(Handle<JSObject> object, | 1404 Handle<Code> CallStubCompiler::CompileCallField(Handle<JSObject> object, |
1404 Handle<JSObject> holder, | 1405 Handle<JSObject> holder, |
1405 PropertyIndex index, | 1406 PropertyIndex index, |
1406 Handle<String> name) { | 1407 Handle<Name> name) { |
1407 // ----------- S t a t e ------------- | 1408 // ----------- S t a t e ------------- |
1408 // rcx : function name | 1409 // rcx : function name |
1409 // rsp[0] : return address | 1410 // rsp[0] : return address |
1410 // rsp[8] : argument argc | 1411 // rsp[8] : argument argc |
1411 // rsp[16] : argument argc - 1 | 1412 // rsp[16] : argument argc - 1 |
1412 // ... | 1413 // ... |
1413 // rsp[argc * 8] : argument 1 | 1414 // rsp[argc * 8] : argument 1 |
1414 // rsp[(argc + 1) * 8] : argument 0 = receiver | 1415 // rsp[(argc + 1) * 8] : argument 0 = receiver |
1415 // ----------------------------------- | 1416 // ----------------------------------- |
1416 Label miss; | 1417 Label miss; |
(...skipping 767 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2184 GenerateMissBranch(); | 2185 GenerateMissBranch(); |
2185 | 2186 |
2186 // Return the generated code. | 2187 // Return the generated code. |
2187 return GetCode(function); | 2188 return GetCode(function); |
2188 } | 2189 } |
2189 | 2190 |
2190 | 2191 |
2191 Handle<Code> CallStubCompiler::CompileCallConstant(Handle<Object> object, | 2192 Handle<Code> CallStubCompiler::CompileCallConstant(Handle<Object> object, |
2192 Handle<JSObject> holder, | 2193 Handle<JSObject> holder, |
2193 Handle<JSFunction> function, | 2194 Handle<JSFunction> function, |
2194 Handle<String> name, | 2195 Handle<Name> name, |
2195 CheckType check) { | 2196 CheckType check) { |
2196 // ----------- S t a t e ------------- | 2197 // ----------- S t a t e ------------- |
2197 // rcx : function name | 2198 // rcx : function name |
2198 // rsp[0] : return address | 2199 // rsp[0] : return address |
2199 // rsp[8] : argument argc | 2200 // rsp[8] : argument argc |
2200 // rsp[16] : argument argc - 1 | 2201 // rsp[16] : argument argc - 1 |
2201 // ... | 2202 // ... |
2202 // rsp[argc * 8] : argument 1 | 2203 // rsp[argc * 8] : argument 1 |
2203 // rsp[(argc + 1) * 8] : argument 0 = receiver | 2204 // rsp[(argc + 1) * 8] : argument 0 = receiver |
2204 // ----------------------------------- | 2205 // ----------------------------------- |
2205 | 2206 |
2206 if (HasCustomCallGenerator(function)) { | 2207 if (HasCustomCallGenerator(function)) { |
2207 Handle<Code> code = CompileCustomCall(object, holder, | 2208 Handle<Code> code = CompileCustomCall(object, holder, |
2208 Handle<JSGlobalPropertyCell>::null(), | 2209 Handle<JSGlobalPropertyCell>::null(), |
2209 function, name); | 2210 function, Handle<String>::cast(name)); |
2210 // A null handle means bail out to the regular compiler code below. | 2211 // A null handle means bail out to the regular compiler code below. |
2211 if (!code.is_null()) return code; | 2212 if (!code.is_null()) return code; |
2212 } | 2213 } |
2213 | 2214 |
2214 Label miss; | 2215 Label miss; |
2215 GenerateNameCheck(name, &miss); | 2216 GenerateNameCheck(name, &miss); |
2216 | 2217 |
2217 // Get the receiver from the stack. | 2218 // Get the receiver from the stack. |
2218 const int argc = arguments().immediate(); | 2219 const int argc = arguments().immediate(); |
2219 __ movq(rdx, Operand(rsp, (argc + 1) * kPointerSize)); | 2220 __ movq(rdx, Operand(rsp, (argc + 1) * kPointerSize)); |
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2322 __ bind(&miss); | 2323 __ bind(&miss); |
2323 GenerateMissBranch(); | 2324 GenerateMissBranch(); |
2324 | 2325 |
2325 // Return the generated code. | 2326 // Return the generated code. |
2326 return GetCode(function); | 2327 return GetCode(function); |
2327 } | 2328 } |
2328 | 2329 |
2329 | 2330 |
2330 Handle<Code> CallStubCompiler::CompileCallInterceptor(Handle<JSObject> object, | 2331 Handle<Code> CallStubCompiler::CompileCallInterceptor(Handle<JSObject> object, |
2331 Handle<JSObject> holder, | 2332 Handle<JSObject> holder, |
2332 Handle<String> name) { | 2333 Handle<Name> name) { |
2333 // ----------- S t a t e ------------- | 2334 // ----------- S t a t e ------------- |
2334 // rcx : function name | 2335 // rcx : function name |
2335 // rsp[0] : return address | 2336 // rsp[0] : return address |
2336 // rsp[8] : argument argc | 2337 // rsp[8] : argument argc |
2337 // rsp[16] : argument argc - 1 | 2338 // rsp[16] : argument argc - 1 |
2338 // ... | 2339 // ... |
2339 // rsp[argc * 8] : argument 1 | 2340 // rsp[argc * 8] : argument 1 |
2340 // rsp[(argc + 1) * 8] : argument 0 = receiver | 2341 // rsp[(argc + 1) * 8] : argument 0 = receiver |
2341 // ----------------------------------- | 2342 // ----------------------------------- |
2342 Label miss; | 2343 Label miss; |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2385 // Return the generated code. | 2386 // Return the generated code. |
2386 return GetCode(Code::INTERCEPTOR, name); | 2387 return GetCode(Code::INTERCEPTOR, name); |
2387 } | 2388 } |
2388 | 2389 |
2389 | 2390 |
2390 Handle<Code> CallStubCompiler::CompileCallGlobal( | 2391 Handle<Code> CallStubCompiler::CompileCallGlobal( |
2391 Handle<JSObject> object, | 2392 Handle<JSObject> object, |
2392 Handle<GlobalObject> holder, | 2393 Handle<GlobalObject> holder, |
2393 Handle<JSGlobalPropertyCell> cell, | 2394 Handle<JSGlobalPropertyCell> cell, |
2394 Handle<JSFunction> function, | 2395 Handle<JSFunction> function, |
2395 Handle<String> name) { | 2396 Handle<Name> name) { |
2396 // ----------- S t a t e ------------- | 2397 // ----------- S t a t e ------------- |
2397 // rcx : function name | 2398 // rcx : function name |
2398 // rsp[0] : return address | 2399 // rsp[0] : return address |
2399 // rsp[8] : argument argc | 2400 // rsp[8] : argument argc |
2400 // rsp[16] : argument argc - 1 | 2401 // rsp[16] : argument argc - 1 |
2401 // ... | 2402 // ... |
2402 // rsp[argc * 8] : argument 1 | 2403 // rsp[argc * 8] : argument 1 |
2403 // rsp[(argc + 1) * 8] : argument 0 = receiver | 2404 // rsp[(argc + 1) * 8] : argument 0 = receiver |
2404 // ----------------------------------- | 2405 // ----------------------------------- |
2405 | 2406 |
2406 if (HasCustomCallGenerator(function)) { | 2407 if (HasCustomCallGenerator(function)) { |
2407 Handle<Code> code = CompileCustomCall(object, holder, cell, function, name); | 2408 Handle<Code> code = CompileCustomCall( |
| 2409 object, holder, cell, function, Handle<String>::cast(name)); |
2408 // A null handle means bail out to the regular compiler code below. | 2410 // A null handle means bail out to the regular compiler code below. |
2409 if (!code.is_null()) return code; | 2411 if (!code.is_null()) return code; |
2410 } | 2412 } |
2411 | 2413 |
2412 Label miss; | 2414 Label miss; |
2413 GenerateNameCheck(name, &miss); | 2415 GenerateNameCheck(name, &miss); |
2414 | 2416 |
2415 // Get the number of arguments. | 2417 // Get the number of arguments. |
2416 const int argc = arguments().immediate(); | 2418 const int argc = arguments().immediate(); |
2417 GenerateGlobalReceiverCheck(object, holder, name, &miss); | 2419 GenerateGlobalReceiverCheck(object, holder, name, &miss); |
(...skipping 28 matching lines...) Expand all Loading... |
2446 GenerateMissBranch(); | 2448 GenerateMissBranch(); |
2447 | 2449 |
2448 // Return the generated code. | 2450 // Return the generated code. |
2449 return GetCode(Code::NORMAL, name); | 2451 return GetCode(Code::NORMAL, name); |
2450 } | 2452 } |
2451 | 2453 |
2452 | 2454 |
2453 Handle<Code> StoreStubCompiler::CompileStoreField(Handle<JSObject> object, | 2455 Handle<Code> StoreStubCompiler::CompileStoreField(Handle<JSObject> object, |
2454 int index, | 2456 int index, |
2455 Handle<Map> transition, | 2457 Handle<Map> transition, |
2456 Handle<String> name) { | 2458 Handle<Name> name) { |
2457 // ----------- S t a t e ------------- | 2459 // ----------- S t a t e ------------- |
2458 // -- rax : value | 2460 // -- rax : value |
2459 // -- rcx : name | 2461 // -- rcx : name |
2460 // -- rdx : receiver | 2462 // -- rdx : receiver |
2461 // -- rsp[0] : return address | 2463 // -- rsp[0] : return address |
2462 // ----------------------------------- | 2464 // ----------------------------------- |
2463 Label miss; | 2465 Label miss; |
2464 | 2466 |
2465 // Generate store field code. Preserves receiver and name on jump to miss. | 2467 // Generate store field code. Preserves receiver and name on jump to miss. |
2466 GenerateStoreField(masm(), | 2468 GenerateStoreField(masm(), |
(...skipping 10 matching lines...) Expand all Loading... |
2477 __ Jump(ic, RelocInfo::CODE_TARGET); | 2479 __ Jump(ic, RelocInfo::CODE_TARGET); |
2478 | 2480 |
2479 // Return the generated code. | 2481 // Return the generated code. |
2480 return GetCode(transition.is_null() | 2482 return GetCode(transition.is_null() |
2481 ? Code::FIELD | 2483 ? Code::FIELD |
2482 : Code::MAP_TRANSITION, name); | 2484 : Code::MAP_TRANSITION, name); |
2483 } | 2485 } |
2484 | 2486 |
2485 | 2487 |
2486 Handle<Code> StoreStubCompiler::CompileStoreCallback( | 2488 Handle<Code> StoreStubCompiler::CompileStoreCallback( |
2487 Handle<String> name, | 2489 Handle<Name> name, |
2488 Handle<JSObject> receiver, | 2490 Handle<JSObject> receiver, |
2489 Handle<JSObject> holder, | 2491 Handle<JSObject> holder, |
2490 Handle<AccessorInfo> callback) { | 2492 Handle<AccessorInfo> callback) { |
2491 // ----------- S t a t e ------------- | 2493 // ----------- S t a t e ------------- |
2492 // -- rax : value | 2494 // -- rax : value |
2493 // -- rcx : name | 2495 // -- rcx : name |
2494 // -- rdx : receiver | 2496 // -- rdx : receiver |
2495 // -- rsp[0] : return address | 2497 // -- rsp[0] : return address |
2496 // ----------------------------------- | 2498 // ----------------------------------- |
2497 Label miss; | 2499 Label miss; |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2564 } | 2566 } |
2565 __ ret(0); | 2567 __ ret(0); |
2566 } | 2568 } |
2567 | 2569 |
2568 | 2570 |
2569 #undef __ | 2571 #undef __ |
2570 #define __ ACCESS_MASM(masm()) | 2572 #define __ ACCESS_MASM(masm()) |
2571 | 2573 |
2572 | 2574 |
2573 Handle<Code> StoreStubCompiler::CompileStoreViaSetter( | 2575 Handle<Code> StoreStubCompiler::CompileStoreViaSetter( |
2574 Handle<String> name, | 2576 Handle<Name> name, |
2575 Handle<JSObject> receiver, | 2577 Handle<JSObject> receiver, |
2576 Handle<JSObject> holder, | 2578 Handle<JSObject> holder, |
2577 Handle<JSFunction> setter) { | 2579 Handle<JSFunction> setter) { |
2578 // ----------- S t a t e ------------- | 2580 // ----------- S t a t e ------------- |
2579 // -- rax : value | 2581 // -- rax : value |
2580 // -- rcx : name | 2582 // -- rcx : name |
2581 // -- rdx : receiver | 2583 // -- rdx : receiver |
2582 // -- rsp[0] : return address | 2584 // -- rsp[0] : return address |
2583 // ----------------------------------- | 2585 // ----------------------------------- |
2584 Label miss; | 2586 Label miss; |
2585 | 2587 |
2586 // Check that the maps haven't changed. | 2588 // Check that the maps haven't changed. |
2587 __ JumpIfSmi(rdx, &miss); | 2589 __ JumpIfSmi(rdx, &miss); |
2588 CheckPrototypes(receiver, rdx, holder, rbx, r8, rdi, name, &miss); | 2590 CheckPrototypes(receiver, rdx, holder, rbx, r8, rdi, name, &miss); |
2589 | 2591 |
2590 GenerateStoreViaSetter(masm(), setter); | 2592 GenerateStoreViaSetter(masm(), setter); |
2591 | 2593 |
2592 __ bind(&miss); | 2594 __ bind(&miss); |
2593 Handle<Code> ic = isolate()->builtins()->StoreIC_Miss(); | 2595 Handle<Code> ic = isolate()->builtins()->StoreIC_Miss(); |
2594 __ Jump(ic, RelocInfo::CODE_TARGET); | 2596 __ Jump(ic, RelocInfo::CODE_TARGET); |
2595 | 2597 |
2596 // Return the generated code. | 2598 // Return the generated code. |
2597 return GetCode(Code::CALLBACKS, name); | 2599 return GetCode(Code::CALLBACKS, name); |
2598 } | 2600 } |
2599 | 2601 |
2600 | 2602 |
2601 Handle<Code> StoreStubCompiler::CompileStoreInterceptor( | 2603 Handle<Code> StoreStubCompiler::CompileStoreInterceptor( |
2602 Handle<JSObject> receiver, | 2604 Handle<JSObject> receiver, |
2603 Handle<String> name) { | 2605 Handle<Name> name) { |
2604 // ----------- S t a t e ------------- | 2606 // ----------- S t a t e ------------- |
2605 // -- rax : value | 2607 // -- rax : value |
2606 // -- rcx : name | 2608 // -- rcx : name |
2607 // -- rdx : receiver | 2609 // -- rdx : receiver |
2608 // -- rsp[0] : return address | 2610 // -- rsp[0] : return address |
2609 // ----------------------------------- | 2611 // ----------------------------------- |
2610 Label miss; | 2612 Label miss; |
2611 | 2613 |
2612 // Check that the map of the object hasn't changed. | 2614 // Check that the map of the object hasn't changed. |
2613 __ CheckMap(rdx, Handle<Map>(receiver->map()), &miss, | 2615 __ CheckMap(rdx, Handle<Map>(receiver->map()), &miss, |
(...skipping 26 matching lines...) Expand all Loading... |
2640 __ Jump(ic, RelocInfo::CODE_TARGET); | 2642 __ Jump(ic, RelocInfo::CODE_TARGET); |
2641 | 2643 |
2642 // Return the generated code. | 2644 // Return the generated code. |
2643 return GetCode(Code::INTERCEPTOR, name); | 2645 return GetCode(Code::INTERCEPTOR, name); |
2644 } | 2646 } |
2645 | 2647 |
2646 | 2648 |
2647 Handle<Code> StoreStubCompiler::CompileStoreGlobal( | 2649 Handle<Code> StoreStubCompiler::CompileStoreGlobal( |
2648 Handle<GlobalObject> object, | 2650 Handle<GlobalObject> object, |
2649 Handle<JSGlobalPropertyCell> cell, | 2651 Handle<JSGlobalPropertyCell> cell, |
2650 Handle<String> name) { | 2652 Handle<Name> name) { |
2651 // ----------- S t a t e ------------- | 2653 // ----------- S t a t e ------------- |
2652 // -- rax : value | 2654 // -- rax : value |
2653 // -- rcx : name | 2655 // -- rcx : name |
2654 // -- rdx : receiver | 2656 // -- rdx : receiver |
2655 // -- rsp[0] : return address | 2657 // -- rsp[0] : return address |
2656 // ----------------------------------- | 2658 // ----------------------------------- |
2657 Label miss; | 2659 Label miss; |
2658 | 2660 |
2659 // Check that the map of the global has not changed. | 2661 // Check that the map of the global has not changed. |
2660 __ Cmp(FieldOperand(rdx, HeapObject::kMapOffset), | 2662 __ Cmp(FieldOperand(rdx, HeapObject::kMapOffset), |
(...skipping 27 matching lines...) Expand all Loading... |
2688 __ Jump(ic, RelocInfo::CODE_TARGET); | 2690 __ Jump(ic, RelocInfo::CODE_TARGET); |
2689 | 2691 |
2690 // Return the generated code. | 2692 // Return the generated code. |
2691 return GetCode(Code::NORMAL, name); | 2693 return GetCode(Code::NORMAL, name); |
2692 } | 2694 } |
2693 | 2695 |
2694 | 2696 |
2695 Handle<Code> KeyedStoreStubCompiler::CompileStoreField(Handle<JSObject> object, | 2697 Handle<Code> KeyedStoreStubCompiler::CompileStoreField(Handle<JSObject> object, |
2696 int index, | 2698 int index, |
2697 Handle<Map> transition, | 2699 Handle<Map> transition, |
2698 Handle<String> name) { | 2700 Handle<Name> name) { |
2699 // ----------- S t a t e ------------- | 2701 // ----------- S t a t e ------------- |
2700 // -- rax : value | 2702 // -- rax : value |
2701 // -- rcx : key | 2703 // -- rcx : key |
2702 // -- rdx : receiver | 2704 // -- rdx : receiver |
2703 // -- rsp[0] : return address | 2705 // -- rsp[0] : return address |
2704 // ----------------------------------- | 2706 // ----------------------------------- |
2705 Label miss; | 2707 Label miss; |
2706 | 2708 |
2707 Counters* counters = isolate()->counters(); | 2709 Counters* counters = isolate()->counters(); |
2708 __ IncrementCounter(counters->keyed_store_field(), 1); | 2710 __ IncrementCounter(counters->keyed_store_field(), 1); |
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2791 __ jmp(ic, RelocInfo::CODE_TARGET); | 2793 __ jmp(ic, RelocInfo::CODE_TARGET); |
2792 | 2794 |
2793 // Return the generated code. | 2795 // Return the generated code. |
2794 return GetCode(Code::NORMAL, factory()->empty_string(), POLYMORPHIC); | 2796 return GetCode(Code::NORMAL, factory()->empty_string(), POLYMORPHIC); |
2795 } | 2797 } |
2796 | 2798 |
2797 | 2799 |
2798 Handle<Code> LoadStubCompiler::CompileLoadNonexistent( | 2800 Handle<Code> LoadStubCompiler::CompileLoadNonexistent( |
2799 Handle<JSObject> object, | 2801 Handle<JSObject> object, |
2800 Handle<JSObject> last, | 2802 Handle<JSObject> last, |
2801 Handle<String> name, | 2803 Handle<Name> name, |
2802 Handle<GlobalObject> global) { | 2804 Handle<GlobalObject> global) { |
2803 // ----------- S t a t e ------------- | 2805 // ----------- S t a t e ------------- |
2804 // -- rax : receiver | 2806 // -- rax : receiver |
2805 // -- rcx : name | 2807 // -- rcx : name |
2806 // -- rsp[0] : return address | 2808 // -- rsp[0] : return address |
2807 // ----------------------------------- | 2809 // ----------------------------------- |
2808 Label miss; | 2810 Label miss; |
2809 | 2811 |
2810 // Check that receiver is not a smi. | 2812 // Check that receiver is not a smi. |
2811 __ JumpIfSmi(rax, &miss); | 2813 __ JumpIfSmi(rax, &miss); |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2850 } | 2852 } |
2851 | 2853 |
2852 | 2854 |
2853 Register* KeyedLoadStubCompiler::registers() { | 2855 Register* KeyedLoadStubCompiler::registers() { |
2854 // receiver, name, scratch1, scratch2, scratch3, scratch4. | 2856 // receiver, name, scratch1, scratch2, scratch3, scratch4. |
2855 static Register registers[] = { rdx, rax, rbx, rcx, rdi, r8 }; | 2857 static Register registers[] = { rdx, rax, rbx, rcx, rdi, r8 }; |
2856 return registers; | 2858 return registers; |
2857 } | 2859 } |
2858 | 2860 |
2859 | 2861 |
2860 void KeyedLoadStubCompiler::GenerateNameCheck(Handle<String> name, | 2862 void KeyedLoadStubCompiler::GenerateNameCheck(Handle<Name> name, |
2861 Register name_reg, | 2863 Register name_reg, |
2862 Label* miss) { | 2864 Label* miss) { |
2863 __ Cmp(name_reg, name); | 2865 __ Cmp(name_reg, name); |
2864 __ j(not_equal, miss); | 2866 __ j(not_equal, miss); |
2865 } | 2867 } |
2866 | 2868 |
2867 | 2869 |
2868 #undef __ | 2870 #undef __ |
2869 #define __ ACCESS_MASM(masm) | 2871 #define __ ACCESS_MASM(masm) |
2870 | 2872 |
(...skipping 27 matching lines...) Expand all Loading... |
2898 } | 2900 } |
2899 | 2901 |
2900 | 2902 |
2901 #undef __ | 2903 #undef __ |
2902 #define __ ACCESS_MASM(masm()) | 2904 #define __ ACCESS_MASM(masm()) |
2903 | 2905 |
2904 | 2906 |
2905 Handle<Code> LoadStubCompiler::CompileLoadViaGetter( | 2907 Handle<Code> LoadStubCompiler::CompileLoadViaGetter( |
2906 Handle<JSObject> receiver, | 2908 Handle<JSObject> receiver, |
2907 Handle<JSObject> holder, | 2909 Handle<JSObject> holder, |
2908 Handle<String> name, | 2910 Handle<Name> name, |
2909 Handle<JSFunction> getter) { | 2911 Handle<JSFunction> getter) { |
2910 // ----------- S t a t e ------------- | 2912 // ----------- S t a t e ------------- |
2911 // -- rax : receiver | 2913 // -- rax : receiver |
2912 // -- rcx : name | 2914 // -- rcx : name |
2913 // -- rsp[0] : return address | 2915 // -- rsp[0] : return address |
2914 // ----------------------------------- | 2916 // ----------------------------------- |
2915 Label miss; | 2917 Label miss; |
2916 | 2918 |
2917 // Check that the maps haven't changed. | 2919 // Check that the maps haven't changed. |
2918 __ JumpIfSmi(rax, &miss); | 2920 __ JumpIfSmi(rax, &miss); |
2919 CheckPrototypes(receiver, rax, holder, rbx, rdx, rdi, name, &miss); | 2921 CheckPrototypes(receiver, rax, holder, rbx, rdx, rdi, name, &miss); |
2920 | 2922 |
2921 GenerateLoadViaGetter(masm(), getter), | 2923 GenerateLoadViaGetter(masm(), getter), |
2922 | 2924 |
2923 __ bind(&miss); | 2925 __ bind(&miss); |
2924 GenerateLoadMiss(masm(), Code::LOAD_IC); | 2926 GenerateLoadMiss(masm(), Code::LOAD_IC); |
2925 | 2927 |
2926 // Return the generated code. | 2928 // Return the generated code. |
2927 return GetCode(Code::CALLBACKS, name); | 2929 return GetCode(Code::CALLBACKS, name); |
2928 } | 2930 } |
2929 | 2931 |
2930 | 2932 |
2931 Handle<Code> LoadStubCompiler::CompileLoadGlobal( | 2933 Handle<Code> LoadStubCompiler::CompileLoadGlobal( |
2932 Handle<JSObject> object, | 2934 Handle<JSObject> object, |
2933 Handle<GlobalObject> holder, | 2935 Handle<GlobalObject> holder, |
2934 Handle<JSGlobalPropertyCell> cell, | 2936 Handle<JSGlobalPropertyCell> cell, |
2935 Handle<String> name, | 2937 Handle<Name> name, |
2936 bool is_dont_delete) { | 2938 bool is_dont_delete) { |
2937 // ----------- S t a t e ------------- | 2939 // ----------- S t a t e ------------- |
2938 // -- rax : receiver | 2940 // -- rax : receiver |
2939 // -- rcx : name | 2941 // -- rcx : name |
2940 // -- rsp[0] : return address | 2942 // -- rsp[0] : return address |
2941 // ----------------------------------- | 2943 // ----------------------------------- |
2942 Label miss; | 2944 Label miss; |
2943 | 2945 |
2944 // Check that the maps haven't changed. | 2946 // Check that the maps haven't changed. |
2945 __ JumpIfSmi(rax, &miss); | 2947 __ JumpIfSmi(rax, &miss); |
(...skipping 752 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3698 __ jmp(ic_slow, RelocInfo::CODE_TARGET); | 3700 __ jmp(ic_slow, RelocInfo::CODE_TARGET); |
3699 } | 3701 } |
3700 } | 3702 } |
3701 | 3703 |
3702 | 3704 |
3703 #undef __ | 3705 #undef __ |
3704 | 3706 |
3705 } } // namespace v8::internal | 3707 } } // namespace v8::internal |
3706 | 3708 |
3707 #endif // V8_TARGET_ARCH_X64 | 3709 #endif // V8_TARGET_ARCH_X64 |
OLD | NEW |