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 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
134 __ bind(&miss); | 134 __ bind(&miss); |
135 __ pop(offset); | 135 __ pop(offset); |
136 } | 136 } |
137 } | 137 } |
138 | 138 |
139 | 139 |
140 // Helper function used to check that the dictionary doesn't contain | 140 // Helper function used to check that the dictionary doesn't contain |
141 // the property. This function may return false negatives, so miss_label | 141 // the property. This function may return false negatives, so miss_label |
142 // must always call a backup property check that is complete. | 142 // must always call a backup property check that is complete. |
143 // This function is safe to call if the receiver has fast properties. | 143 // This function is safe to call if the receiver has fast properties. |
144 // Name must be an internalized string and receiver must be a heap object. | 144 // Name must be unique and receiver must be a heap object. |
145 static void GenerateDictionaryNegativeLookup(MacroAssembler* masm, | 145 static void GenerateDictionaryNegativeLookup(MacroAssembler* masm, |
146 Label* miss_label, | 146 Label* miss_label, |
147 Register receiver, | 147 Register receiver, |
148 Handle<String> name, | 148 Handle<Name> name, |
149 Register r0, | 149 Register r0, |
150 Register r1) { | 150 Register r1) { |
151 ASSERT(name->IsInternalizedString()); | 151 ASSERT(name->IsUniqueName()); |
152 Counters* counters = masm->isolate()->counters(); | 152 Counters* counters = masm->isolate()->counters(); |
153 __ IncrementCounter(counters->negative_lookups(), 1); | 153 __ IncrementCounter(counters->negative_lookups(), 1); |
154 __ IncrementCounter(counters->negative_lookups_miss(), 1); | 154 __ IncrementCounter(counters->negative_lookups_miss(), 1); |
155 | 155 |
156 __ mov(r0, FieldOperand(receiver, HeapObject::kMapOffset)); | 156 __ mov(r0, FieldOperand(receiver, HeapObject::kMapOffset)); |
157 | 157 |
158 const int kInterceptorOrAccessCheckNeededMask = | 158 const int kInterceptorOrAccessCheckNeededMask = |
159 (1 << Map::kHasNamedInterceptor) | (1 << Map::kIsAccessCheckNeeded); | 159 (1 << Map::kHasNamedInterceptor) | (1 << Map::kIsAccessCheckNeeded); |
160 | 160 |
161 // Bail out if the receiver has a named interceptor or requires access checks. | 161 // Bail out if the receiver has a named interceptor or requires access checks. |
162 __ test_b(FieldOperand(r0, Map::kBitFieldOffset), | 162 __ test_b(FieldOperand(r0, Map::kBitFieldOffset), |
163 kInterceptorOrAccessCheckNeededMask); | 163 kInterceptorOrAccessCheckNeededMask); |
164 __ j(not_zero, miss_label); | 164 __ j(not_zero, miss_label); |
165 | 165 |
166 // Check that receiver is a JSObject. | 166 // Check that receiver is a JSObject. |
167 __ CmpInstanceType(r0, FIRST_SPEC_OBJECT_TYPE); | 167 __ CmpInstanceType(r0, FIRST_SPEC_OBJECT_TYPE); |
168 __ j(below, miss_label); | 168 __ j(below, miss_label); |
169 | 169 |
170 // Load properties array. | 170 // Load properties array. |
171 Register properties = r0; | 171 Register properties = r0; |
172 __ mov(properties, FieldOperand(receiver, JSObject::kPropertiesOffset)); | 172 __ mov(properties, FieldOperand(receiver, JSObject::kPropertiesOffset)); |
173 | 173 |
174 // Check that the properties array is a dictionary. | 174 // Check that the properties array is a dictionary. |
175 __ cmp(FieldOperand(properties, HeapObject::kMapOffset), | 175 __ cmp(FieldOperand(properties, HeapObject::kMapOffset), |
176 Immediate(masm->isolate()->factory()->hash_table_map())); | 176 Immediate(masm->isolate()->factory()->hash_table_map())); |
177 __ j(not_equal, miss_label); | 177 __ j(not_equal, miss_label); |
178 | 178 |
179 Label done; | 179 Label done; |
180 StringDictionaryLookupStub::GenerateNegativeLookup(masm, | 180 NameDictionaryLookupStub::GenerateNegativeLookup(masm, |
181 miss_label, | 181 miss_label, |
182 &done, | 182 &done, |
183 properties, | 183 properties, |
184 name, | 184 name, |
185 r1); | 185 r1); |
186 __ bind(&done); | 186 __ bind(&done); |
187 __ DecrementCounter(counters->negative_lookups_miss(), 1); | 187 __ DecrementCounter(counters->negative_lookups_miss(), 1); |
188 } | 188 } |
189 | 189 |
190 | 190 |
191 void StubCache::GenerateProbe(MacroAssembler* masm, | 191 void StubCache::GenerateProbe(MacroAssembler* masm, |
192 Code::Flags flags, | 192 Code::Flags flags, |
193 Register receiver, | 193 Register receiver, |
194 Register name, | 194 Register name, |
195 Register scratch, | 195 Register scratch, |
(...skipping 24 matching lines...) Expand all Loading... |
220 Register offset = scratch; | 220 Register offset = scratch; |
221 scratch = no_reg; | 221 scratch = no_reg; |
222 | 222 |
223 Counters* counters = masm->isolate()->counters(); | 223 Counters* counters = masm->isolate()->counters(); |
224 __ IncrementCounter(counters->megamorphic_stub_cache_probes(), 1); | 224 __ IncrementCounter(counters->megamorphic_stub_cache_probes(), 1); |
225 | 225 |
226 // Check that the receiver isn't a smi. | 226 // Check that the receiver isn't a smi. |
227 __ JumpIfSmi(receiver, &miss); | 227 __ JumpIfSmi(receiver, &miss); |
228 | 228 |
229 // Get the map of the receiver and compute the hash. | 229 // Get the map of the receiver and compute the hash. |
230 __ mov(offset, FieldOperand(name, String::kHashFieldOffset)); | 230 __ mov(offset, FieldOperand(name, Name::kHashFieldOffset)); |
231 __ add(offset, FieldOperand(receiver, HeapObject::kMapOffset)); | 231 __ add(offset, FieldOperand(receiver, HeapObject::kMapOffset)); |
232 __ xor_(offset, flags); | 232 __ xor_(offset, flags); |
233 // We mask out the last two bits because they are not part of the hash and | 233 // We mask out the last two bits because they are not part of the hash and |
234 // they are always 01 for maps. Also in the two 'and' instructions below. | 234 // they are always 01 for maps. Also in the two 'and' instructions below. |
235 __ and_(offset, (kPrimaryTableSize - 1) << kHeapObjectTagSize); | 235 __ and_(offset, (kPrimaryTableSize - 1) << kHeapObjectTagSize); |
236 // ProbeTable expects the offset to be pointer scaled, which it is, because | 236 // ProbeTable expects the offset to be pointer scaled, which it is, because |
237 // the heap object tag size is 2 and the pointer size log 2 is also 2. | 237 // the heap object tag size is 2 and the pointer size log 2 is also 2. |
238 ASSERT(kHeapObjectTagSize == kPointerSizeLog2); | 238 ASSERT(kHeapObjectTagSize == kPointerSizeLog2); |
239 | 239 |
240 // Probe the primary table. | 240 // Probe the primary table. |
241 ProbeTable(isolate(), masm, flags, kPrimary, name, receiver, offset, extra); | 241 ProbeTable(isolate(), masm, flags, kPrimary, name, receiver, offset, extra); |
242 | 242 |
243 // Primary miss: Compute hash for secondary probe. | 243 // Primary miss: Compute hash for secondary probe. |
244 __ mov(offset, FieldOperand(name, String::kHashFieldOffset)); | 244 __ mov(offset, FieldOperand(name, Name::kHashFieldOffset)); |
245 __ add(offset, FieldOperand(receiver, HeapObject::kMapOffset)); | 245 __ add(offset, FieldOperand(receiver, HeapObject::kMapOffset)); |
246 __ xor_(offset, flags); | 246 __ xor_(offset, flags); |
247 __ and_(offset, (kPrimaryTableSize - 1) << kHeapObjectTagSize); | 247 __ and_(offset, (kPrimaryTableSize - 1) << kHeapObjectTagSize); |
248 __ sub(offset, name); | 248 __ sub(offset, name); |
249 __ add(offset, Immediate(flags)); | 249 __ add(offset, Immediate(flags)); |
250 __ and_(offset, (kSecondaryTableSize - 1) << kHeapObjectTagSize); | 250 __ and_(offset, (kSecondaryTableSize - 1) << kHeapObjectTagSize); |
251 | 251 |
252 // Probe the secondary table. | 252 // Probe the secondary table. |
253 ProbeTable( | 253 ProbeTable( |
254 isolate(), masm, flags, kSecondary, name, receiver, offset, extra); | 254 isolate(), masm, flags, kSecondary, name, receiver, offset, extra); |
(...skipping 284 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
539 Register name, | 539 Register name, |
540 Code::ExtraICState extra_state) | 540 Code::ExtraICState extra_state) |
541 : stub_compiler_(stub_compiler), | 541 : stub_compiler_(stub_compiler), |
542 arguments_(arguments), | 542 arguments_(arguments), |
543 name_(name), | 543 name_(name), |
544 extra_state_(extra_state) {} | 544 extra_state_(extra_state) {} |
545 | 545 |
546 void Compile(MacroAssembler* masm, | 546 void Compile(MacroAssembler* masm, |
547 Handle<JSObject> object, | 547 Handle<JSObject> object, |
548 Handle<JSObject> holder, | 548 Handle<JSObject> holder, |
549 Handle<String> name, | 549 Handle<Name> name, |
550 LookupResult* lookup, | 550 LookupResult* lookup, |
551 Register receiver, | 551 Register receiver, |
552 Register scratch1, | 552 Register scratch1, |
553 Register scratch2, | 553 Register scratch2, |
554 Register scratch3, | 554 Register scratch3, |
555 Label* miss) { | 555 Label* miss) { |
556 ASSERT(holder->HasNamedInterceptor()); | 556 ASSERT(holder->HasNamedInterceptor()); |
557 ASSERT(!holder->GetNamedInterceptor()->getter()->IsUndefined()); | 557 ASSERT(!holder->GetNamedInterceptor()->getter()->IsUndefined()); |
558 | 558 |
559 // Check that the receiver isn't a smi. | 559 // Check that the receiver isn't a smi. |
(...skipping 11 matching lines...) Expand all Loading... |
571 | 571 |
572 private: | 572 private: |
573 void CompileCacheable(MacroAssembler* masm, | 573 void CompileCacheable(MacroAssembler* masm, |
574 Handle<JSObject> object, | 574 Handle<JSObject> object, |
575 Register receiver, | 575 Register receiver, |
576 Register scratch1, | 576 Register scratch1, |
577 Register scratch2, | 577 Register scratch2, |
578 Register scratch3, | 578 Register scratch3, |
579 Handle<JSObject> interceptor_holder, | 579 Handle<JSObject> interceptor_holder, |
580 LookupResult* lookup, | 580 LookupResult* lookup, |
581 Handle<String> name, | 581 Handle<Name> name, |
582 const CallOptimization& optimization, | 582 const CallOptimization& optimization, |
583 Label* miss_label) { | 583 Label* miss_label) { |
584 ASSERT(optimization.is_constant_call()); | 584 ASSERT(optimization.is_constant_call()); |
585 ASSERT(!lookup->holder()->IsGlobalObject()); | 585 ASSERT(!lookup->holder()->IsGlobalObject()); |
586 | 586 |
587 int depth1 = kInvalidProtoDepth; | 587 int depth1 = kInvalidProtoDepth; |
588 int depth2 = kInvalidProtoDepth; | 588 int depth2 = kInvalidProtoDepth; |
589 bool can_do_fast_api_call = false; | 589 bool can_do_fast_api_call = false; |
590 if (optimization.is_simple_api_call() && | 590 if (optimization.is_simple_api_call() && |
591 !lookup->holder()->IsGlobalObject()) { | 591 !lookup->holder()->IsGlobalObject()) { |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
664 FreeSpaceForFastApiCall(masm, scratch1); | 664 FreeSpaceForFastApiCall(masm, scratch1); |
665 } | 665 } |
666 } | 666 } |
667 | 667 |
668 void CompileRegular(MacroAssembler* masm, | 668 void CompileRegular(MacroAssembler* masm, |
669 Handle<JSObject> object, | 669 Handle<JSObject> object, |
670 Register receiver, | 670 Register receiver, |
671 Register scratch1, | 671 Register scratch1, |
672 Register scratch2, | 672 Register scratch2, |
673 Register scratch3, | 673 Register scratch3, |
674 Handle<String> name, | 674 Handle<Name> name, |
675 Handle<JSObject> interceptor_holder, | 675 Handle<JSObject> interceptor_holder, |
676 Label* miss_label) { | 676 Label* miss_label) { |
677 Register holder = | 677 Register holder = |
678 stub_compiler_->CheckPrototypes(object, receiver, interceptor_holder, | 678 stub_compiler_->CheckPrototypes(object, receiver, interceptor_holder, |
679 scratch1, scratch2, scratch3, | 679 scratch1, scratch2, scratch3, |
680 name, miss_label); | 680 name, miss_label); |
681 | 681 |
682 FrameScope scope(masm, StackFrame::INTERNAL); | 682 FrameScope scope(masm, StackFrame::INTERNAL); |
683 // Save the name_ register across the call. | 683 // Save the name_ register across the call. |
684 __ push(name_); | 684 __ push(name_); |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
752 __ jmp(code, RelocInfo::CODE_TARGET); | 752 __ jmp(code, RelocInfo::CODE_TARGET); |
753 } | 753 } |
754 | 754 |
755 | 755 |
756 // Both name_reg and receiver_reg are preserved on jumps to miss_label, | 756 // Both name_reg and receiver_reg are preserved on jumps to miss_label, |
757 // but may be destroyed if store is successful. | 757 // but may be destroyed if store is successful. |
758 void StubCompiler::GenerateStoreField(MacroAssembler* masm, | 758 void StubCompiler::GenerateStoreField(MacroAssembler* masm, |
759 Handle<JSObject> object, | 759 Handle<JSObject> object, |
760 int index, | 760 int index, |
761 Handle<Map> transition, | 761 Handle<Map> transition, |
762 Handle<String> name, | 762 Handle<Name> name, |
763 Register receiver_reg, | 763 Register receiver_reg, |
764 Register name_reg, | 764 Register name_reg, |
765 Register scratch1, | 765 Register scratch1, |
766 Register scratch2, | 766 Register scratch2, |
767 Label* miss_label) { | 767 Label* miss_label) { |
768 LookupResult lookup(masm->isolate()); | 768 LookupResult lookup(masm->isolate()); |
769 object->Lookup(*name, &lookup); | 769 object->Lookup(*name, &lookup); |
770 if (lookup.IsFound() && (lookup.IsReadOnly() || !lookup.IsCacheable())) { | 770 if (lookup.IsFound() && (lookup.IsReadOnly() || !lookup.IsCacheable())) { |
771 // In sloppy mode, we could just return the value and be done. However, we | 771 // In sloppy mode, we could just return the value and be done. However, we |
772 // might be in strict mode, where we have to throw. Since we cannot tell, | 772 // might be in strict mode, where we have to throw. Since we cannot tell, |
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
886 // Return the value (register eax). | 886 // Return the value (register eax). |
887 __ ret(0); | 887 __ ret(0); |
888 } | 888 } |
889 | 889 |
890 | 890 |
891 // Generate code to check that a global property cell is empty. Create | 891 // Generate code to check that a global property cell is empty. Create |
892 // the property cell at compilation time if no cell exists for the | 892 // the property cell at compilation time if no cell exists for the |
893 // property. | 893 // property. |
894 static void GenerateCheckPropertyCell(MacroAssembler* masm, | 894 static void GenerateCheckPropertyCell(MacroAssembler* masm, |
895 Handle<GlobalObject> global, | 895 Handle<GlobalObject> global, |
896 Handle<String> name, | 896 Handle<Name> name, |
897 Register scratch, | 897 Register scratch, |
898 Label* miss) { | 898 Label* miss) { |
899 Handle<JSGlobalPropertyCell> cell = | 899 Handle<JSGlobalPropertyCell> cell = |
900 GlobalObject::EnsurePropertyCell(global, name); | 900 GlobalObject::EnsurePropertyCell(global, name); |
901 ASSERT(cell->value()->IsTheHole()); | 901 ASSERT(cell->value()->IsTheHole()); |
902 Handle<Oddball> the_hole = masm->isolate()->factory()->the_hole_value(); | 902 Handle<Oddball> the_hole = masm->isolate()->factory()->the_hole_value(); |
903 if (Serializer::enabled()) { | 903 if (Serializer::enabled()) { |
904 __ mov(scratch, Immediate(cell)); | 904 __ mov(scratch, Immediate(cell)); |
905 __ cmp(FieldOperand(scratch, JSGlobalPropertyCell::kValueOffset), | 905 __ cmp(FieldOperand(scratch, JSGlobalPropertyCell::kValueOffset), |
906 Immediate(the_hole)); | 906 Immediate(the_hole)); |
907 } else { | 907 } else { |
908 __ cmp(Operand::Cell(cell), Immediate(the_hole)); | 908 __ cmp(Operand::Cell(cell), Immediate(the_hole)); |
909 } | 909 } |
910 __ j(not_equal, miss); | 910 __ j(not_equal, miss); |
911 } | 911 } |
912 | 912 |
913 | 913 |
914 // Calls GenerateCheckPropertyCell for each global object in the prototype chain | 914 // Calls GenerateCheckPropertyCell for each global object in the prototype chain |
915 // from object to (but not including) holder. | 915 // from object to (but not including) holder. |
916 static void GenerateCheckPropertyCells(MacroAssembler* masm, | 916 static void GenerateCheckPropertyCells(MacroAssembler* masm, |
917 Handle<JSObject> object, | 917 Handle<JSObject> object, |
918 Handle<JSObject> holder, | 918 Handle<JSObject> holder, |
919 Handle<String> name, | 919 Handle<Name> name, |
920 Register scratch, | 920 Register scratch, |
921 Label* miss) { | 921 Label* miss) { |
922 Handle<JSObject> current = object; | 922 Handle<JSObject> current = object; |
923 while (!current.is_identical_to(holder)) { | 923 while (!current.is_identical_to(holder)) { |
924 if (current->IsGlobalObject()) { | 924 if (current->IsGlobalObject()) { |
925 GenerateCheckPropertyCell(masm, | 925 GenerateCheckPropertyCell(masm, |
926 Handle<GlobalObject>::cast(current), | 926 Handle<GlobalObject>::cast(current), |
927 name, | 927 name, |
928 scratch, | 928 scratch, |
929 miss); | 929 miss); |
930 } | 930 } |
931 current = Handle<JSObject>(JSObject::cast(current->GetPrototype())); | 931 current = Handle<JSObject>(JSObject::cast(current->GetPrototype())); |
932 } | 932 } |
933 } | 933 } |
934 | 934 |
935 #undef __ | 935 #undef __ |
936 #define __ ACCESS_MASM(masm()) | 936 #define __ ACCESS_MASM(masm()) |
937 | 937 |
938 | 938 |
939 Register StubCompiler::CheckPrototypes(Handle<JSObject> object, | 939 Register StubCompiler::CheckPrototypes(Handle<JSObject> object, |
940 Register object_reg, | 940 Register object_reg, |
941 Handle<JSObject> holder, | 941 Handle<JSObject> holder, |
942 Register holder_reg, | 942 Register holder_reg, |
943 Register scratch1, | 943 Register scratch1, |
944 Register scratch2, | 944 Register scratch2, |
945 Handle<String> name, | 945 Handle<Name> name, |
946 int save_at_depth, | 946 int save_at_depth, |
947 Label* miss) { | 947 Label* miss) { |
948 // Make sure there's no overlap between holder and object registers. | 948 // Make sure there's no overlap between holder and object registers. |
949 ASSERT(!scratch1.is(object_reg) && !scratch1.is(holder_reg)); | 949 ASSERT(!scratch1.is(object_reg) && !scratch1.is(holder_reg)); |
950 ASSERT(!scratch2.is(object_reg) && !scratch2.is(holder_reg) | 950 ASSERT(!scratch2.is(object_reg) && !scratch2.is(holder_reg) |
951 && !scratch2.is(scratch1)); | 951 && !scratch2.is(scratch1)); |
952 | 952 |
953 // Keep track of the current object in register reg. | 953 // Keep track of the current object in register reg. |
954 Register reg = object_reg; | 954 Register reg = object_reg; |
955 Handle<JSObject> current = object; | 955 Handle<JSObject> current = object; |
956 int depth = 0; | 956 int depth = 0; |
957 | 957 |
958 if (save_at_depth == depth) { | 958 if (save_at_depth == depth) { |
959 __ mov(Operand(esp, kPointerSize), reg); | 959 __ mov(Operand(esp, kPointerSize), reg); |
960 } | 960 } |
961 | 961 |
962 // Traverse the prototype chain and check the maps in the prototype chain for | 962 // Traverse the prototype chain and check the maps in the prototype chain for |
963 // fast and global objects or do negative lookup for normal objects. | 963 // fast and global objects or do negative lookup for normal objects. |
964 while (!current.is_identical_to(holder)) { | 964 while (!current.is_identical_to(holder)) { |
965 ++depth; | 965 ++depth; |
966 | 966 |
967 // Only global objects and objects that do not require access | 967 // Only global objects and objects that do not require access |
968 // checks are allowed in stubs. | 968 // checks are allowed in stubs. |
969 ASSERT(current->IsJSGlobalProxy() || !current->IsAccessCheckNeeded()); | 969 ASSERT(current->IsJSGlobalProxy() || !current->IsAccessCheckNeeded()); |
970 | 970 |
971 Handle<JSObject> prototype(JSObject::cast(current->GetPrototype())); | 971 Handle<JSObject> prototype(JSObject::cast(current->GetPrototype())); |
972 if (!current->HasFastProperties() && | 972 if (!current->HasFastProperties() && |
973 !current->IsJSGlobalObject() && | 973 !current->IsJSGlobalObject() && |
974 !current->IsJSGlobalProxy()) { | 974 !current->IsJSGlobalProxy()) { |
975 if (!name->IsInternalizedString()) { | 975 if (!name->IsUniqueName()) { |
976 name = factory()->InternalizeString(name); | 976 ASSERT(name->IsString()); |
| 977 name = factory()->InternalizeString(Handle<String>::cast(name)); |
977 } | 978 } |
978 ASSERT(current->property_dictionary()->FindEntry(*name) == | 979 ASSERT(current->property_dictionary()->FindEntry(*name) == |
979 StringDictionary::kNotFound); | 980 NameDictionary::kNotFound); |
980 | 981 |
981 GenerateDictionaryNegativeLookup(masm(), miss, reg, name, | 982 GenerateDictionaryNegativeLookup(masm(), miss, reg, name, |
982 scratch1, scratch2); | 983 scratch1, scratch2); |
983 | 984 |
984 __ mov(scratch1, FieldOperand(reg, HeapObject::kMapOffset)); | 985 __ mov(scratch1, FieldOperand(reg, HeapObject::kMapOffset)); |
985 reg = holder_reg; // From now on the object will be in holder_reg. | 986 reg = holder_reg; // From now on the object will be in holder_reg. |
986 __ mov(reg, FieldOperand(scratch1, Map::kPrototypeOffset)); | 987 __ mov(reg, FieldOperand(scratch1, Map::kPrototypeOffset)); |
987 } else { | 988 } else { |
988 bool in_new_space = heap()->InNewSpace(*prototype); | 989 bool in_new_space = heap()->InNewSpace(*prototype); |
989 Handle<Map> current_map(current->map()); | 990 Handle<Map> current_map(current->map()); |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1044 } | 1045 } |
1045 | 1046 |
1046 | 1047 |
1047 void StubCompiler::GenerateLoadField(Handle<JSObject> object, | 1048 void StubCompiler::GenerateLoadField(Handle<JSObject> object, |
1048 Handle<JSObject> holder, | 1049 Handle<JSObject> holder, |
1049 Register receiver, | 1050 Register receiver, |
1050 Register scratch1, | 1051 Register scratch1, |
1051 Register scratch2, | 1052 Register scratch2, |
1052 Register scratch3, | 1053 Register scratch3, |
1053 PropertyIndex index, | 1054 PropertyIndex index, |
1054 Handle<String> name, | 1055 Handle<Name> name, |
1055 Label* miss) { | 1056 Label* miss) { |
1056 // Check that the receiver isn't a smi. | 1057 // Check that the receiver isn't a smi. |
1057 __ JumpIfSmi(receiver, miss); | 1058 __ JumpIfSmi(receiver, miss); |
1058 | 1059 |
1059 // Check the prototype chain. | 1060 // Check the prototype chain. |
1060 Register reg = CheckPrototypes( | 1061 Register reg = CheckPrototypes( |
1061 object, receiver, holder, scratch1, scratch2, scratch3, name, miss); | 1062 object, receiver, holder, scratch1, scratch2, scratch3, name, miss); |
1062 | 1063 |
1063 // Get the value from the properties. | 1064 // Get the value from the properties. |
1064 GenerateFastPropertyLoad(masm(), eax, reg, holder, index); | 1065 GenerateFastPropertyLoad(masm(), eax, reg, holder, index); |
1065 __ ret(0); | 1066 __ ret(0); |
1066 } | 1067 } |
1067 | 1068 |
1068 | 1069 |
1069 void StubCompiler::GenerateDictionaryLoadCallback(Register receiver, | 1070 void StubCompiler::GenerateDictionaryLoadCallback(Register receiver, |
1070 Register name_reg, | 1071 Register name_reg, |
1071 Register scratch1, | 1072 Register scratch1, |
1072 Register scratch2, | 1073 Register scratch2, |
1073 Register scratch3, | 1074 Register scratch3, |
1074 Handle<AccessorInfo> callback, | 1075 Handle<AccessorInfo> callback, |
1075 Handle<String> name, | 1076 Handle<Name> name, |
1076 Label* miss) { | 1077 Label* miss) { |
1077 ASSERT(!receiver.is(scratch2)); | 1078 ASSERT(!receiver.is(scratch2)); |
1078 ASSERT(!receiver.is(scratch3)); | 1079 ASSERT(!receiver.is(scratch3)); |
1079 Register dictionary = scratch1; | 1080 Register dictionary = scratch1; |
1080 bool must_preserve_dictionary_reg = receiver.is(dictionary); | 1081 bool must_preserve_dictionary_reg = receiver.is(dictionary); |
1081 | 1082 |
1082 // Load the properties dictionary. | 1083 // Load the properties dictionary. |
1083 if (must_preserve_dictionary_reg) { | 1084 if (must_preserve_dictionary_reg) { |
1084 __ push(dictionary); | 1085 __ push(dictionary); |
1085 } | 1086 } |
1086 __ mov(dictionary, FieldOperand(receiver, JSObject::kPropertiesOffset)); | 1087 __ mov(dictionary, FieldOperand(receiver, JSObject::kPropertiesOffset)); |
1087 | 1088 |
1088 // Probe the dictionary. | 1089 // Probe the dictionary. |
1089 Label probe_done, pop_and_miss; | 1090 Label probe_done, pop_and_miss; |
1090 StringDictionaryLookupStub::GeneratePositiveLookup(masm(), | 1091 NameDictionaryLookupStub::GeneratePositiveLookup(masm(), |
1091 &pop_and_miss, | 1092 &pop_and_miss, |
1092 &probe_done, | 1093 &probe_done, |
1093 dictionary, | 1094 dictionary, |
1094 name_reg, | 1095 name_reg, |
1095 scratch2, | 1096 scratch2, |
1096 scratch3); | 1097 scratch3); |
1097 __ bind(&pop_and_miss); | 1098 __ bind(&pop_and_miss); |
1098 if (must_preserve_dictionary_reg) { | 1099 if (must_preserve_dictionary_reg) { |
1099 __ pop(dictionary); | 1100 __ pop(dictionary); |
1100 } | 1101 } |
1101 __ jmp(miss); | 1102 __ jmp(miss); |
1102 __ bind(&probe_done); | 1103 __ bind(&probe_done); |
1103 | 1104 |
1104 // If probing finds an entry in the dictionary, scratch2 contains the | 1105 // If probing finds an entry in the dictionary, scratch2 contains the |
1105 // index into the dictionary. Check that the value is the callback. | 1106 // index into the dictionary. Check that the value is the callback. |
1106 Register index = scratch2; | 1107 Register index = scratch2; |
1107 const int kElementsStartOffset = | 1108 const int kElementsStartOffset = |
1108 StringDictionary::kHeaderSize + | 1109 NameDictionary::kHeaderSize + |
1109 StringDictionary::kElementsStartIndex * kPointerSize; | 1110 NameDictionary::kElementsStartIndex * kPointerSize; |
1110 const int kValueOffset = kElementsStartOffset + kPointerSize; | 1111 const int kValueOffset = kElementsStartOffset + kPointerSize; |
1111 __ mov(scratch3, | 1112 __ mov(scratch3, |
1112 Operand(dictionary, index, times_4, kValueOffset - kHeapObjectTag)); | 1113 Operand(dictionary, index, times_4, kValueOffset - kHeapObjectTag)); |
1113 if (must_preserve_dictionary_reg) { | 1114 if (must_preserve_dictionary_reg) { |
1114 __ pop(dictionary); | 1115 __ pop(dictionary); |
1115 } | 1116 } |
1116 __ cmp(scratch3, callback); | 1117 __ cmp(scratch3, callback); |
1117 __ j(not_equal, miss); | 1118 __ j(not_equal, miss); |
1118 } | 1119 } |
1119 | 1120 |
1120 | 1121 |
1121 void StubCompiler::GenerateLoadCallback(Handle<JSObject> object, | 1122 void StubCompiler::GenerateLoadCallback(Handle<JSObject> object, |
1122 Handle<JSObject> holder, | 1123 Handle<JSObject> holder, |
1123 Register receiver, | 1124 Register receiver, |
1124 Register name_reg, | 1125 Register name_reg, |
1125 Register scratch1, | 1126 Register scratch1, |
1126 Register scratch2, | 1127 Register scratch2, |
1127 Register scratch3, | 1128 Register scratch3, |
1128 Register scratch4, | 1129 Register scratch4, |
1129 Handle<AccessorInfo> callback, | 1130 Handle<AccessorInfo> callback, |
1130 Handle<String> name, | 1131 Handle<Name> name, |
1131 Label* miss) { | 1132 Label* miss) { |
1132 // Check that the receiver isn't a smi. | 1133 // Check that the receiver isn't a smi. |
1133 __ JumpIfSmi(receiver, miss); | 1134 __ JumpIfSmi(receiver, miss); |
1134 | 1135 |
1135 // Check that the maps haven't changed. | 1136 // Check that the maps haven't changed. |
1136 Register reg = CheckPrototypes(object, receiver, holder, scratch1, | 1137 Register reg = CheckPrototypes(object, receiver, holder, scratch1, |
1137 scratch2, scratch3, name, miss); | 1138 scratch2, scratch3, name, miss); |
1138 | 1139 |
1139 if (!holder->HasFastProperties() && !holder->IsJSGlobalObject()) { | 1140 if (!holder->HasFastProperties() && !holder->IsJSGlobalObject()) { |
1140 GenerateDictionaryLoadCallback( | 1141 GenerateDictionaryLoadCallback( |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1186 } | 1187 } |
1187 | 1188 |
1188 | 1189 |
1189 void StubCompiler::GenerateLoadConstant(Handle<JSObject> object, | 1190 void StubCompiler::GenerateLoadConstant(Handle<JSObject> object, |
1190 Handle<JSObject> holder, | 1191 Handle<JSObject> holder, |
1191 Register receiver, | 1192 Register receiver, |
1192 Register scratch1, | 1193 Register scratch1, |
1193 Register scratch2, | 1194 Register scratch2, |
1194 Register scratch3, | 1195 Register scratch3, |
1195 Handle<JSFunction> value, | 1196 Handle<JSFunction> value, |
1196 Handle<String> name, | 1197 Handle<Name> name, |
1197 Label* miss) { | 1198 Label* miss) { |
1198 // Check that the receiver isn't a smi. | 1199 // Check that the receiver isn't a smi. |
1199 __ JumpIfSmi(receiver, miss); | 1200 __ JumpIfSmi(receiver, miss); |
1200 | 1201 |
1201 // Check that the maps haven't changed. | 1202 // Check that the maps haven't changed. |
1202 CheckPrototypes( | 1203 CheckPrototypes( |
1203 object, receiver, holder, scratch1, scratch2, scratch3, name, miss); | 1204 object, receiver, holder, scratch1, scratch2, scratch3, name, miss); |
1204 | 1205 |
1205 // Return the constant value. | 1206 // Return the constant value. |
1206 __ LoadHeapObject(eax, value); | 1207 __ LoadHeapObject(eax, value); |
1207 __ ret(0); | 1208 __ ret(0); |
1208 } | 1209 } |
1209 | 1210 |
1210 | 1211 |
1211 void StubCompiler::GenerateLoadInterceptor(Handle<JSObject> object, | 1212 void StubCompiler::GenerateLoadInterceptor(Handle<JSObject> object, |
1212 Handle<JSObject> interceptor_holder, | 1213 Handle<JSObject> interceptor_holder, |
1213 LookupResult* lookup, | 1214 LookupResult* lookup, |
1214 Register receiver, | 1215 Register receiver, |
1215 Register name_reg, | 1216 Register name_reg, |
1216 Register scratch1, | 1217 Register scratch1, |
1217 Register scratch2, | 1218 Register scratch2, |
1218 Register scratch3, | 1219 Register scratch3, |
1219 Handle<String> name, | 1220 Handle<Name> name, |
1220 Label* miss) { | 1221 Label* miss) { |
1221 ASSERT(interceptor_holder->HasNamedInterceptor()); | 1222 ASSERT(interceptor_holder->HasNamedInterceptor()); |
1222 ASSERT(!interceptor_holder->GetNamedInterceptor()->getter()->IsUndefined()); | 1223 ASSERT(!interceptor_holder->GetNamedInterceptor()->getter()->IsUndefined()); |
1223 | 1224 |
1224 // Check that the receiver isn't a smi. | 1225 // Check that the receiver isn't a smi. |
1225 __ JumpIfSmi(receiver, miss); | 1226 __ JumpIfSmi(receiver, miss); |
1226 | 1227 |
1227 // So far the most popular follow ups for interceptor loads are FIELD | 1228 // So far the most popular follow ups for interceptor loads are FIELD |
1228 // and CALLBACKS, so inline only them, other cases may be added | 1229 // and CALLBACKS, so inline only them, other cases may be added |
1229 // later. | 1230 // later. |
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1359 __ push(scratch2); // restore old return address | 1360 __ push(scratch2); // restore old return address |
1360 | 1361 |
1361 ExternalReference ref = | 1362 ExternalReference ref = |
1362 ExternalReference(IC_Utility(IC::kLoadPropertyWithInterceptorForLoad), | 1363 ExternalReference(IC_Utility(IC::kLoadPropertyWithInterceptorForLoad), |
1363 isolate()); | 1364 isolate()); |
1364 __ TailCallExternalReference(ref, 6, 1); | 1365 __ TailCallExternalReference(ref, 6, 1); |
1365 } | 1366 } |
1366 } | 1367 } |
1367 | 1368 |
1368 | 1369 |
1369 void CallStubCompiler::GenerateNameCheck(Handle<String> name, Label* miss) { | 1370 void CallStubCompiler::GenerateNameCheck(Handle<Name> name, Label* miss) { |
1370 if (kind_ == Code::KEYED_CALL_IC) { | 1371 if (kind_ == Code::KEYED_CALL_IC) { |
1371 __ cmp(ecx, Immediate(name)); | 1372 __ cmp(ecx, Immediate(name)); |
1372 __ j(not_equal, miss); | 1373 __ j(not_equal, miss); |
1373 } | 1374 } |
1374 } | 1375 } |
1375 | 1376 |
1376 | 1377 |
1377 void CallStubCompiler::GenerateGlobalReceiverCheck(Handle<JSObject> object, | 1378 void CallStubCompiler::GenerateGlobalReceiverCheck(Handle<JSObject> object, |
1378 Handle<JSObject> holder, | 1379 Handle<JSObject> holder, |
1379 Handle<String> name, | 1380 Handle<Name> name, |
1380 Label* miss) { | 1381 Label* miss) { |
1381 ASSERT(holder->IsGlobalObject()); | 1382 ASSERT(holder->IsGlobalObject()); |
1382 | 1383 |
1383 // Get the number of arguments. | 1384 // Get the number of arguments. |
1384 const int argc = arguments().immediate(); | 1385 const int argc = arguments().immediate(); |
1385 | 1386 |
1386 // Get the receiver from the stack. | 1387 // Get the receiver from the stack. |
1387 __ mov(edx, Operand(esp, (argc + 1) * kPointerSize)); | 1388 __ mov(edx, Operand(esp, (argc + 1) * kPointerSize)); |
1388 | 1389 |
1389 | 1390 |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1431 isolate()->stub_cache()->ComputeCallMiss(arguments().immediate(), | 1432 isolate()->stub_cache()->ComputeCallMiss(arguments().immediate(), |
1432 kind_, | 1433 kind_, |
1433 extra_state_); | 1434 extra_state_); |
1434 __ jmp(code, RelocInfo::CODE_TARGET); | 1435 __ jmp(code, RelocInfo::CODE_TARGET); |
1435 } | 1436 } |
1436 | 1437 |
1437 | 1438 |
1438 Handle<Code> CallStubCompiler::CompileCallField(Handle<JSObject> object, | 1439 Handle<Code> CallStubCompiler::CompileCallField(Handle<JSObject> object, |
1439 Handle<JSObject> holder, | 1440 Handle<JSObject> holder, |
1440 PropertyIndex index, | 1441 PropertyIndex index, |
1441 Handle<String> name) { | 1442 Handle<Name> name) { |
1442 // ----------- S t a t e ------------- | 1443 // ----------- S t a t e ------------- |
1443 // -- ecx : name | 1444 // -- ecx : name |
1444 // -- esp[0] : return address | 1445 // -- esp[0] : return address |
1445 // -- esp[(argc - n) * 4] : arg[n] (zero-based) | 1446 // -- esp[(argc - n) * 4] : arg[n] (zero-based) |
1446 // -- ... | 1447 // -- ... |
1447 // -- esp[(argc + 1) * 4] : receiver | 1448 // -- esp[(argc + 1) * 4] : receiver |
1448 // ----------------------------------- | 1449 // ----------------------------------- |
1449 Label miss; | 1450 Label miss; |
1450 | 1451 |
1451 GenerateNameCheck(name, &miss); | 1452 GenerateNameCheck(name, &miss); |
(...skipping 912 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2364 GenerateMissBranch(); | 2365 GenerateMissBranch(); |
2365 | 2366 |
2366 // Return the generated code. | 2367 // Return the generated code. |
2367 return GetCode(function); | 2368 return GetCode(function); |
2368 } | 2369 } |
2369 | 2370 |
2370 | 2371 |
2371 Handle<Code> CallStubCompiler::CompileCallConstant(Handle<Object> object, | 2372 Handle<Code> CallStubCompiler::CompileCallConstant(Handle<Object> object, |
2372 Handle<JSObject> holder, | 2373 Handle<JSObject> holder, |
2373 Handle<JSFunction> function, | 2374 Handle<JSFunction> function, |
2374 Handle<String> name, | 2375 Handle<Name> name, |
2375 CheckType check) { | 2376 CheckType check) { |
2376 // ----------- S t a t e ------------- | 2377 // ----------- S t a t e ------------- |
2377 // -- ecx : name | 2378 // -- ecx : name |
2378 // -- esp[0] : return address | 2379 // -- esp[0] : return address |
2379 // -- esp[(argc - n) * 4] : arg[n] (zero-based) | 2380 // -- esp[(argc - n) * 4] : arg[n] (zero-based) |
2380 // -- ... | 2381 // -- ... |
2381 // -- esp[(argc + 1) * 4] : receiver | 2382 // -- esp[(argc + 1) * 4] : receiver |
2382 // ----------------------------------- | 2383 // ----------------------------------- |
2383 | 2384 |
2384 if (HasCustomCallGenerator(function)) { | 2385 if (HasCustomCallGenerator(function)) { |
2385 Handle<Code> code = CompileCustomCall(object, holder, | 2386 Handle<Code> code = CompileCustomCall(object, holder, |
2386 Handle<JSGlobalPropertyCell>::null(), | 2387 Handle<JSGlobalPropertyCell>::null(), |
2387 function, name); | 2388 function, Handle<String>::cast(name)); |
2388 // A null handle means bail out to the regular compiler code below. | 2389 // A null handle means bail out to the regular compiler code below. |
2389 if (!code.is_null()) return code; | 2390 if (!code.is_null()) return code; |
2390 } | 2391 } |
2391 | 2392 |
2392 Label miss; | 2393 Label miss; |
2393 GenerateNameCheck(name, &miss); | 2394 GenerateNameCheck(name, &miss); |
2394 | 2395 |
2395 // Get the receiver from the stack. | 2396 // Get the receiver from the stack. |
2396 const int argc = arguments().immediate(); | 2397 const int argc = arguments().immediate(); |
2397 __ mov(edx, Operand(esp, (argc + 1) * kPointerSize)); | 2398 __ mov(edx, Operand(esp, (argc + 1) * kPointerSize)); |
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2498 __ bind(&miss); | 2499 __ bind(&miss); |
2499 GenerateMissBranch(); | 2500 GenerateMissBranch(); |
2500 | 2501 |
2501 // Return the generated code. | 2502 // Return the generated code. |
2502 return GetCode(function); | 2503 return GetCode(function); |
2503 } | 2504 } |
2504 | 2505 |
2505 | 2506 |
2506 Handle<Code> CallStubCompiler::CompileCallInterceptor(Handle<JSObject> object, | 2507 Handle<Code> CallStubCompiler::CompileCallInterceptor(Handle<JSObject> object, |
2507 Handle<JSObject> holder, | 2508 Handle<JSObject> holder, |
2508 Handle<String> name) { | 2509 Handle<Name> name) { |
2509 // ----------- S t a t e ------------- | 2510 // ----------- S t a t e ------------- |
2510 // -- ecx : name | 2511 // -- ecx : name |
2511 // -- esp[0] : return address | 2512 // -- esp[0] : return address |
2512 // -- esp[(argc - n) * 4] : arg[n] (zero-based) | 2513 // -- esp[(argc - n) * 4] : arg[n] (zero-based) |
2513 // -- ... | 2514 // -- ... |
2514 // -- esp[(argc + 1) * 4] : receiver | 2515 // -- esp[(argc + 1) * 4] : receiver |
2515 // ----------------------------------- | 2516 // ----------------------------------- |
2516 Label miss; | 2517 Label miss; |
2517 | 2518 |
2518 GenerateNameCheck(name, &miss); | 2519 GenerateNameCheck(name, &miss); |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2560 // Return the generated code. | 2561 // Return the generated code. |
2561 return GetCode(Code::INTERCEPTOR, name); | 2562 return GetCode(Code::INTERCEPTOR, name); |
2562 } | 2563 } |
2563 | 2564 |
2564 | 2565 |
2565 Handle<Code> CallStubCompiler::CompileCallGlobal( | 2566 Handle<Code> CallStubCompiler::CompileCallGlobal( |
2566 Handle<JSObject> object, | 2567 Handle<JSObject> object, |
2567 Handle<GlobalObject> holder, | 2568 Handle<GlobalObject> holder, |
2568 Handle<JSGlobalPropertyCell> cell, | 2569 Handle<JSGlobalPropertyCell> cell, |
2569 Handle<JSFunction> function, | 2570 Handle<JSFunction> function, |
2570 Handle<String> name) { | 2571 Handle<Name> name) { |
2571 // ----------- S t a t e ------------- | 2572 // ----------- S t a t e ------------- |
2572 // -- ecx : name | 2573 // -- ecx : name |
2573 // -- esp[0] : return address | 2574 // -- esp[0] : return address |
2574 // -- esp[(argc - n) * 4] : arg[n] (zero-based) | 2575 // -- esp[(argc - n) * 4] : arg[n] (zero-based) |
2575 // -- ... | 2576 // -- ... |
2576 // -- esp[(argc + 1) * 4] : receiver | 2577 // -- esp[(argc + 1) * 4] : receiver |
2577 // ----------------------------------- | 2578 // ----------------------------------- |
2578 | 2579 |
2579 if (HasCustomCallGenerator(function)) { | 2580 if (HasCustomCallGenerator(function)) { |
2580 Handle<Code> code = CompileCustomCall(object, holder, cell, function, name); | 2581 Handle<Code> code = CompileCustomCall( |
| 2582 object, holder, cell, function, Handle<String>::cast(name)); |
2581 // A null handle means bail out to the regular compiler code below. | 2583 // A null handle means bail out to the regular compiler code below. |
2582 if (!code.is_null()) return code; | 2584 if (!code.is_null()) return code; |
2583 } | 2585 } |
2584 | 2586 |
2585 Label miss; | 2587 Label miss; |
2586 GenerateNameCheck(name, &miss); | 2588 GenerateNameCheck(name, &miss); |
2587 | 2589 |
2588 // Get the number of arguments. | 2590 // Get the number of arguments. |
2589 const int argc = arguments().immediate(); | 2591 const int argc = arguments().immediate(); |
2590 GenerateGlobalReceiverCheck(object, holder, name, &miss); | 2592 GenerateGlobalReceiverCheck(object, holder, name, &miss); |
(...skipping 28 matching lines...) Expand all Loading... |
2619 GenerateMissBranch(); | 2621 GenerateMissBranch(); |
2620 | 2622 |
2621 // Return the generated code. | 2623 // Return the generated code. |
2622 return GetCode(Code::NORMAL, name); | 2624 return GetCode(Code::NORMAL, name); |
2623 } | 2625 } |
2624 | 2626 |
2625 | 2627 |
2626 Handle<Code> StoreStubCompiler::CompileStoreField(Handle<JSObject> object, | 2628 Handle<Code> StoreStubCompiler::CompileStoreField(Handle<JSObject> object, |
2627 int index, | 2629 int index, |
2628 Handle<Map> transition, | 2630 Handle<Map> transition, |
2629 Handle<String> name) { | 2631 Handle<Name> name) { |
2630 // ----------- S t a t e ------------- | 2632 // ----------- S t a t e ------------- |
2631 // -- eax : value | 2633 // -- eax : value |
2632 // -- ecx : name | 2634 // -- ecx : name |
2633 // -- edx : receiver | 2635 // -- edx : receiver |
2634 // -- esp[0] : return address | 2636 // -- esp[0] : return address |
2635 // ----------------------------------- | 2637 // ----------------------------------- |
2636 Label miss; | 2638 Label miss; |
2637 | 2639 |
2638 // Generate store field code. Trashes the name register. | 2640 // Generate store field code. Trashes the name register. |
2639 GenerateStoreField(masm(), | 2641 GenerateStoreField(masm(), |
(...skipping 10 matching lines...) Expand all Loading... |
2650 __ jmp(ic, RelocInfo::CODE_TARGET); | 2652 __ jmp(ic, RelocInfo::CODE_TARGET); |
2651 | 2653 |
2652 // Return the generated code. | 2654 // Return the generated code. |
2653 return GetCode(transition.is_null() | 2655 return GetCode(transition.is_null() |
2654 ? Code::FIELD | 2656 ? Code::FIELD |
2655 : Code::MAP_TRANSITION, name); | 2657 : Code::MAP_TRANSITION, name); |
2656 } | 2658 } |
2657 | 2659 |
2658 | 2660 |
2659 Handle<Code> StoreStubCompiler::CompileStoreCallback( | 2661 Handle<Code> StoreStubCompiler::CompileStoreCallback( |
2660 Handle<String> name, | 2662 Handle<Name> name, |
2661 Handle<JSObject> receiver, | 2663 Handle<JSObject> receiver, |
2662 Handle<JSObject> holder, | 2664 Handle<JSObject> holder, |
2663 Handle<AccessorInfo> callback) { | 2665 Handle<AccessorInfo> callback) { |
2664 // ----------- S t a t e ------------- | 2666 // ----------- S t a t e ------------- |
2665 // -- eax : value | 2667 // -- eax : value |
2666 // -- ecx : name | 2668 // -- ecx : name |
2667 // -- edx : receiver | 2669 // -- edx : receiver |
2668 // -- esp[0] : return address | 2670 // -- esp[0] : return address |
2669 // ----------------------------------- | 2671 // ----------------------------------- |
2670 Label miss; | 2672 Label miss; |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2740 } | 2742 } |
2741 __ ret(0); | 2743 __ ret(0); |
2742 } | 2744 } |
2743 | 2745 |
2744 | 2746 |
2745 #undef __ | 2747 #undef __ |
2746 #define __ ACCESS_MASM(masm()) | 2748 #define __ ACCESS_MASM(masm()) |
2747 | 2749 |
2748 | 2750 |
2749 Handle<Code> StoreStubCompiler::CompileStoreViaSetter( | 2751 Handle<Code> StoreStubCompiler::CompileStoreViaSetter( |
2750 Handle<String> name, | 2752 Handle<Name> name, |
2751 Handle<JSObject> receiver, | 2753 Handle<JSObject> receiver, |
2752 Handle<JSObject> holder, | 2754 Handle<JSObject> holder, |
2753 Handle<JSFunction> setter) { | 2755 Handle<JSFunction> setter) { |
2754 // ----------- S t a t e ------------- | 2756 // ----------- S t a t e ------------- |
2755 // -- eax : value | 2757 // -- eax : value |
2756 // -- ecx : name | 2758 // -- ecx : name |
2757 // -- edx : receiver | 2759 // -- edx : receiver |
2758 // -- esp[0] : return address | 2760 // -- esp[0] : return address |
2759 // ----------------------------------- | 2761 // ----------------------------------- |
2760 Label miss; | 2762 Label miss; |
(...skipping 11 matching lines...) Expand all Loading... |
2772 Handle<Code> ic = isolate()->builtins()->StoreIC_Miss(); | 2774 Handle<Code> ic = isolate()->builtins()->StoreIC_Miss(); |
2773 __ jmp(ic, RelocInfo::CODE_TARGET); | 2775 __ jmp(ic, RelocInfo::CODE_TARGET); |
2774 | 2776 |
2775 // Return the generated code. | 2777 // Return the generated code. |
2776 return GetCode(Code::CALLBACKS, name); | 2778 return GetCode(Code::CALLBACKS, name); |
2777 } | 2779 } |
2778 | 2780 |
2779 | 2781 |
2780 Handle<Code> StoreStubCompiler::CompileStoreInterceptor( | 2782 Handle<Code> StoreStubCompiler::CompileStoreInterceptor( |
2781 Handle<JSObject> receiver, | 2783 Handle<JSObject> receiver, |
2782 Handle<String> name) { | 2784 Handle<Name> name) { |
2783 // ----------- S t a t e ------------- | 2785 // ----------- S t a t e ------------- |
2784 // -- eax : value | 2786 // -- eax : value |
2785 // -- ecx : name | 2787 // -- ecx : name |
2786 // -- edx : receiver | 2788 // -- edx : receiver |
2787 // -- esp[0] : return address | 2789 // -- esp[0] : return address |
2788 // ----------------------------------- | 2790 // ----------------------------------- |
2789 Label miss; | 2791 Label miss; |
2790 | 2792 |
2791 // Check that the map of the object hasn't changed. | 2793 // Check that the map of the object hasn't changed. |
2792 __ CheckMap(edx, Handle<Map>(receiver->map()), | 2794 __ CheckMap(edx, Handle<Map>(receiver->map()), |
(...skipping 26 matching lines...) Expand all Loading... |
2819 __ jmp(ic, RelocInfo::CODE_TARGET); | 2821 __ jmp(ic, RelocInfo::CODE_TARGET); |
2820 | 2822 |
2821 // Return the generated code. | 2823 // Return the generated code. |
2822 return GetCode(Code::INTERCEPTOR, name); | 2824 return GetCode(Code::INTERCEPTOR, name); |
2823 } | 2825 } |
2824 | 2826 |
2825 | 2827 |
2826 Handle<Code> StoreStubCompiler::CompileStoreGlobal( | 2828 Handle<Code> StoreStubCompiler::CompileStoreGlobal( |
2827 Handle<GlobalObject> object, | 2829 Handle<GlobalObject> object, |
2828 Handle<JSGlobalPropertyCell> cell, | 2830 Handle<JSGlobalPropertyCell> cell, |
2829 Handle<String> name) { | 2831 Handle<Name> name) { |
2830 // ----------- S t a t e ------------- | 2832 // ----------- S t a t e ------------- |
2831 // -- eax : value | 2833 // -- eax : value |
2832 // -- ecx : name | 2834 // -- ecx : name |
2833 // -- edx : receiver | 2835 // -- edx : receiver |
2834 // -- esp[0] : return address | 2836 // -- esp[0] : return address |
2835 // ----------------------------------- | 2837 // ----------------------------------- |
2836 Label miss; | 2838 Label miss; |
2837 | 2839 |
2838 // Check that the map of the global has not changed. | 2840 // Check that the map of the global has not changed. |
2839 __ cmp(FieldOperand(edx, HeapObject::kMapOffset), | 2841 __ cmp(FieldOperand(edx, HeapObject::kMapOffset), |
(...skipping 27 matching lines...) Expand all Loading... |
2867 __ jmp(ic, RelocInfo::CODE_TARGET); | 2869 __ jmp(ic, RelocInfo::CODE_TARGET); |
2868 | 2870 |
2869 // Return the generated code. | 2871 // Return the generated code. |
2870 return GetCode(Code::NORMAL, name); | 2872 return GetCode(Code::NORMAL, name); |
2871 } | 2873 } |
2872 | 2874 |
2873 | 2875 |
2874 Handle<Code> KeyedStoreStubCompiler::CompileStoreField(Handle<JSObject> object, | 2876 Handle<Code> KeyedStoreStubCompiler::CompileStoreField(Handle<JSObject> object, |
2875 int index, | 2877 int index, |
2876 Handle<Map> transition, | 2878 Handle<Map> transition, |
2877 Handle<String> name) { | 2879 Handle<Name> name) { |
2878 // ----------- S t a t e ------------- | 2880 // ----------- S t a t e ------------- |
2879 // -- eax : value | 2881 // -- eax : value |
2880 // -- ecx : key | 2882 // -- ecx : key |
2881 // -- edx : receiver | 2883 // -- edx : receiver |
2882 // -- esp[0] : return address | 2884 // -- esp[0] : return address |
2883 // ----------------------------------- | 2885 // ----------------------------------- |
2884 Label miss; | 2886 Label miss; |
2885 | 2887 |
2886 Counters* counters = isolate()->counters(); | 2888 Counters* counters = isolate()->counters(); |
2887 __ IncrementCounter(counters->keyed_store_field(), 1); | 2889 __ IncrementCounter(counters->keyed_store_field(), 1); |
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2966 __ jmp(miss_ic, RelocInfo::CODE_TARGET); | 2968 __ jmp(miss_ic, RelocInfo::CODE_TARGET); |
2967 | 2969 |
2968 // Return the generated code. | 2970 // Return the generated code. |
2969 return GetCode(Code::NORMAL, factory()->empty_string(), POLYMORPHIC); | 2971 return GetCode(Code::NORMAL, factory()->empty_string(), POLYMORPHIC); |
2970 } | 2972 } |
2971 | 2973 |
2972 | 2974 |
2973 Handle<Code> LoadStubCompiler::CompileLoadNonexistent( | 2975 Handle<Code> LoadStubCompiler::CompileLoadNonexistent( |
2974 Handle<JSObject> object, | 2976 Handle<JSObject> object, |
2975 Handle<JSObject> last, | 2977 Handle<JSObject> last, |
2976 Handle<String> name, | 2978 Handle<Name> name, |
2977 Handle<GlobalObject> global) { | 2979 Handle<GlobalObject> global) { |
2978 // ----------- S t a t e ------------- | 2980 // ----------- S t a t e ------------- |
2979 // -- ecx : name | 2981 // -- ecx : name |
2980 // -- edx : receiver | 2982 // -- edx : receiver |
2981 // -- esp[0] : return address | 2983 // -- esp[0] : return address |
2982 // ----------------------------------- | 2984 // ----------------------------------- |
2983 Label miss; | 2985 Label miss; |
2984 | 2986 |
2985 // Check that the receiver isn't a smi. | 2987 // Check that the receiver isn't a smi. |
2986 __ JumpIfSmi(edx, &miss); | 2988 __ JumpIfSmi(edx, &miss); |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3026 } | 3028 } |
3027 | 3029 |
3028 | 3030 |
3029 Register* KeyedLoadStubCompiler::registers() { | 3031 Register* KeyedLoadStubCompiler::registers() { |
3030 // receiver, name, scratch1, scratch2, scratch3, scratch4. | 3032 // receiver, name, scratch1, scratch2, scratch3, scratch4. |
3031 static Register registers[] = { edx, ecx, ebx, eax, edi, no_reg }; | 3033 static Register registers[] = { edx, ecx, ebx, eax, edi, no_reg }; |
3032 return registers; | 3034 return registers; |
3033 } | 3035 } |
3034 | 3036 |
3035 | 3037 |
3036 void KeyedLoadStubCompiler::GenerateNameCheck(Handle<String> name, | 3038 void KeyedLoadStubCompiler::GenerateNameCheck(Handle<Name> name, |
3037 Register name_reg, | 3039 Register name_reg, |
3038 Label* miss) { | 3040 Label* miss) { |
3039 __ cmp(name_reg, Immediate(name)); | 3041 __ cmp(name_reg, Immediate(name)); |
3040 __ j(not_equal, miss); | 3042 __ j(not_equal, miss); |
3041 } | 3043 } |
3042 | 3044 |
3043 | 3045 |
3044 #undef __ | 3046 #undef __ |
3045 #define __ ACCESS_MASM(masm) | 3047 #define __ ACCESS_MASM(masm) |
3046 | 3048 |
(...skipping 27 matching lines...) Expand all Loading... |
3074 } | 3076 } |
3075 | 3077 |
3076 | 3078 |
3077 #undef __ | 3079 #undef __ |
3078 #define __ ACCESS_MASM(masm()) | 3080 #define __ ACCESS_MASM(masm()) |
3079 | 3081 |
3080 | 3082 |
3081 Handle<Code> LoadStubCompiler::CompileLoadViaGetter( | 3083 Handle<Code> LoadStubCompiler::CompileLoadViaGetter( |
3082 Handle<JSObject> receiver, | 3084 Handle<JSObject> receiver, |
3083 Handle<JSObject> holder, | 3085 Handle<JSObject> holder, |
3084 Handle<String> name, | 3086 Handle<Name> name, |
3085 Handle<JSFunction> getter) { | 3087 Handle<JSFunction> getter) { |
3086 // ----------- S t a t e ------------- | 3088 // ----------- S t a t e ------------- |
3087 // -- ecx : name | 3089 // -- ecx : name |
3088 // -- edx : receiver | 3090 // -- edx : receiver |
3089 // -- esp[0] : return address | 3091 // -- esp[0] : return address |
3090 // ----------------------------------- | 3092 // ----------------------------------- |
3091 Label miss; | 3093 Label miss; |
3092 | 3094 |
3093 // Check that the maps haven't changed. | 3095 // Check that the maps haven't changed. |
3094 __ JumpIfSmi(edx, &miss); | 3096 __ JumpIfSmi(edx, &miss); |
3095 CheckPrototypes(receiver, edx, holder, ebx, eax, edi, name, &miss); | 3097 CheckPrototypes(receiver, edx, holder, ebx, eax, edi, name, &miss); |
3096 | 3098 |
3097 GenerateLoadViaGetter(masm(), getter); | 3099 GenerateLoadViaGetter(masm(), getter); |
3098 | 3100 |
3099 __ bind(&miss); | 3101 __ bind(&miss); |
3100 GenerateLoadMiss(masm(), Code::LOAD_IC); | 3102 GenerateLoadMiss(masm(), Code::LOAD_IC); |
3101 | 3103 |
3102 // Return the generated code. | 3104 // Return the generated code. |
3103 return GetCode(Code::CALLBACKS, name); | 3105 return GetCode(Code::CALLBACKS, name); |
3104 } | 3106 } |
3105 | 3107 |
3106 | 3108 |
3107 Handle<Code> LoadStubCompiler::CompileLoadGlobal( | 3109 Handle<Code> LoadStubCompiler::CompileLoadGlobal( |
3108 Handle<JSObject> object, | 3110 Handle<JSObject> object, |
3109 Handle<GlobalObject> holder, | 3111 Handle<GlobalObject> holder, |
3110 Handle<JSGlobalPropertyCell> cell, | 3112 Handle<JSGlobalPropertyCell> cell, |
3111 Handle<String> name, | 3113 Handle<Name> name, |
3112 bool is_dont_delete) { | 3114 bool is_dont_delete) { |
3113 // ----------- S t a t e ------------- | 3115 // ----------- S t a t e ------------- |
3114 // -- ecx : name | 3116 // -- ecx : name |
3115 // -- edx : receiver | 3117 // -- edx : receiver |
3116 // -- esp[0] : return address | 3118 // -- esp[0] : return address |
3117 // ----------------------------------- | 3119 // ----------------------------------- |
3118 Label miss; | 3120 Label miss; |
3119 | 3121 |
3120 // Check that the maps haven't changed. | 3122 // Check that the maps haven't changed. |
3121 __ JumpIfSmi(edx, &miss); | 3123 __ JumpIfSmi(edx, &miss); |
(...skipping 801 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3923 __ jmp(ic_slow, RelocInfo::CODE_TARGET); | 3925 __ jmp(ic_slow, RelocInfo::CODE_TARGET); |
3924 } | 3926 } |
3925 } | 3927 } |
3926 | 3928 |
3927 | 3929 |
3928 #undef __ | 3930 #undef __ |
3929 | 3931 |
3930 } } // namespace v8::internal | 3932 } } // namespace v8::internal |
3931 | 3933 |
3932 #endif // V8_TARGET_ARCH_IA32 | 3934 #endif // V8_TARGET_ARCH_IA32 |
OLD | NEW |