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

Side by Side Diff: src/ia32/stub-cache-ia32.cc

Issue 8404030: Version 3.7.1 (Closed) Base URL: http://v8.googlecode.com/svn/trunk/
Patch Set: Created 9 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/ia32/regexp-macro-assembler-ia32.cc ('k') | src/ic.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2011 the V8 project authors. All rights reserved. 1 // Copyright 2011 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 89 matching lines...) Expand 10 before | Expand all | Expand 10 after
100 __ pop(offset); 100 __ pop(offset);
101 } 101 }
102 } 102 }
103 103
104 104
105 // Helper function used to check that the dictionary doesn't contain 105 // Helper function used to check that the dictionary doesn't contain
106 // the property. This function may return false negatives, so miss_label 106 // the property. This function may return false negatives, so miss_label
107 // must always call a backup property check that is complete. 107 // must always call a backup property check that is complete.
108 // This function is safe to call if the receiver has fast properties. 108 // This function is safe to call if the receiver has fast properties.
109 // Name must be a symbol and receiver must be a heap object. 109 // Name must be a symbol and receiver must be a heap object.
110 static MaybeObject* GenerateDictionaryNegativeLookup(MacroAssembler* masm, 110 static void GenerateDictionaryNegativeLookup(MacroAssembler* masm,
111 Label* miss_label, 111 Label* miss_label,
112 Register receiver, 112 Register receiver,
113 String* name, 113 Handle<String> name,
114 Register r0, 114 Register r0,
115 Register r1) { 115 Register r1) {
116 ASSERT(name->IsSymbol()); 116 ASSERT(name->IsSymbol());
117 Counters* counters = masm->isolate()->counters(); 117 Counters* counters = masm->isolate()->counters();
118 __ IncrementCounter(counters->negative_lookups(), 1); 118 __ IncrementCounter(counters->negative_lookups(), 1);
119 __ IncrementCounter(counters->negative_lookups_miss(), 1); 119 __ IncrementCounter(counters->negative_lookups_miss(), 1);
120 120
121 __ mov(r0, FieldOperand(receiver, HeapObject::kMapOffset)); 121 __ mov(r0, FieldOperand(receiver, HeapObject::kMapOffset));
122 122
123 const int kInterceptorOrAccessCheckNeededMask = 123 const int kInterceptorOrAccessCheckNeededMask =
124 (1 << Map::kHasNamedInterceptor) | (1 << Map::kIsAccessCheckNeeded); 124 (1 << Map::kHasNamedInterceptor) | (1 << Map::kIsAccessCheckNeeded);
125 125
126 // Bail out if the receiver has a named interceptor or requires access checks. 126 // Bail out if the receiver has a named interceptor or requires access checks.
127 __ test_b(FieldOperand(r0, Map::kBitFieldOffset), 127 __ test_b(FieldOperand(r0, Map::kBitFieldOffset),
128 kInterceptorOrAccessCheckNeededMask); 128 kInterceptorOrAccessCheckNeededMask);
129 __ j(not_zero, miss_label); 129 __ j(not_zero, miss_label);
130 130
131 // Check that receiver is a JSObject. 131 // Check that receiver is a JSObject.
132 __ CmpInstanceType(r0, FIRST_SPEC_OBJECT_TYPE); 132 __ CmpInstanceType(r0, FIRST_SPEC_OBJECT_TYPE);
133 __ j(below, miss_label); 133 __ j(below, miss_label);
134 134
135 // Load properties array. 135 // Load properties array.
136 Register properties = r0; 136 Register properties = r0;
137 __ mov(properties, FieldOperand(receiver, JSObject::kPropertiesOffset)); 137 __ mov(properties, FieldOperand(receiver, JSObject::kPropertiesOffset));
138 138
139 // Check that the properties array is a dictionary. 139 // Check that the properties array is a dictionary.
140 __ cmp(FieldOperand(properties, HeapObject::kMapOffset), 140 __ cmp(FieldOperand(properties, HeapObject::kMapOffset),
141 Immediate(masm->isolate()->factory()->hash_table_map())); 141 Immediate(masm->isolate()->factory()->hash_table_map()));
142 __ j(not_equal, miss_label); 142 __ j(not_equal, miss_label);
143 143
144 Label done; 144 Label done;
145 StringDictionaryLookupStub::GenerateNegativeLookup(masm,
146 miss_label,
147 &done,
148 properties,
149 name,
150 r1);
151 __ bind(&done);
152 __ DecrementCounter(counters->negative_lookups_miss(), 1);
153 }
154
155
156 // TODO(kmillikin): Eliminate this function when the stub cache is fully
157 // handlified.
158 static MaybeObject* TryGenerateDictionaryNegativeLookup(MacroAssembler* masm,
159 Label* miss_label,
160 Register receiver,
161 String* name,
162 Register r0,
163 Register r1) {
164 ASSERT(name->IsSymbol());
165 Counters* counters = masm->isolate()->counters();
166 __ IncrementCounter(counters->negative_lookups(), 1);
167 __ IncrementCounter(counters->negative_lookups_miss(), 1);
168
169 __ mov(r0, FieldOperand(receiver, HeapObject::kMapOffset));
170
171 const int kInterceptorOrAccessCheckNeededMask =
172 (1 << Map::kHasNamedInterceptor) | (1 << Map::kIsAccessCheckNeeded);
173
174 // Bail out if the receiver has a named interceptor or requires access checks.
175 __ test_b(FieldOperand(r0, Map::kBitFieldOffset),
176 kInterceptorOrAccessCheckNeededMask);
177 __ j(not_zero, miss_label);
178
179 // Check that receiver is a JSObject.
180 __ CmpInstanceType(r0, FIRST_SPEC_OBJECT_TYPE);
181 __ j(below, miss_label);
182
183 // Load properties array.
184 Register properties = r0;
185 __ mov(properties, FieldOperand(receiver, JSObject::kPropertiesOffset));
186
187 // Check that the properties array is a dictionary.
188 __ cmp(FieldOperand(properties, HeapObject::kMapOffset),
189 Immediate(masm->isolate()->factory()->hash_table_map()));
190 __ j(not_equal, miss_label);
191
192 Label done;
145 MaybeObject* result = 193 MaybeObject* result =
146 StringDictionaryLookupStub::GenerateNegativeLookup(masm, 194 StringDictionaryLookupStub::TryGenerateNegativeLookup(masm,
147 miss_label, 195 miss_label,
148 &done, 196 &done,
149 properties, 197 properties,
150 name, 198 name,
151 r1); 199 r1);
152 if (result->IsFailure()) return result; 200 if (result->IsFailure()) return result;
153 201
154 __ bind(&done); 202 __ bind(&done);
155 __ DecrementCounter(counters->negative_lookups_miss(), 1); 203 __ DecrementCounter(counters->negative_lookups_miss(), 1);
156 204
157 return result; 205 return result;
158 } 206 }
159 207
160 208
161 void StubCache::GenerateProbe(MacroAssembler* masm, 209 void StubCache::GenerateProbe(MacroAssembler* masm,
162 Code::Flags flags, 210 Code::Flags flags,
163 Register receiver, 211 Register receiver,
164 Register name, 212 Register name,
165 Register scratch, 213 Register scratch,
166 Register extra, 214 Register extra,
167 Register extra2) { 215 Register extra2) {
168 Isolate* isolate = Isolate::Current();
169 Label miss; 216 Label miss;
170 USE(extra2); // The register extra2 is not used on the ia32 platform.
171 217
172 // Make sure that code is valid. The shifting code relies on the 218 // Assert that code is valid. The shifting code relies on the entry size
173 // entry size being 8. 219 // being 8.
174 ASSERT(sizeof(Entry) == 8); 220 ASSERT(sizeof(Entry) == 8);
175 221
176 // Make sure the flags does not name a specific type. 222 // Assert the flags do not name a specific type.
177 ASSERT(Code::ExtractTypeFromFlags(flags) == 0); 223 ASSERT(Code::ExtractTypeFromFlags(flags) == 0);
178 224
179 // Make sure that there are no register conflicts. 225 // Assert that there are no register conflicts.
180 ASSERT(!scratch.is(receiver)); 226 ASSERT(!scratch.is(receiver));
181 ASSERT(!scratch.is(name)); 227 ASSERT(!scratch.is(name));
182 ASSERT(!extra.is(receiver)); 228 ASSERT(!extra.is(receiver));
183 ASSERT(!extra.is(name)); 229 ASSERT(!extra.is(name));
184 ASSERT(!extra.is(scratch)); 230 ASSERT(!extra.is(scratch));
185 231
186 // Check scratch and extra registers are valid, and extra2 is unused. 232 // Assert scratch and extra registers are valid, and extra2 is unused.
187 ASSERT(!scratch.is(no_reg)); 233 ASSERT(!scratch.is(no_reg));
188 ASSERT(extra2.is(no_reg)); 234 ASSERT(extra2.is(no_reg));
189 235
190 // Check that the receiver isn't a smi. 236 // Check that the receiver isn't a smi.
191 __ JumpIfSmi(receiver, &miss); 237 __ JumpIfSmi(receiver, &miss);
192 238
193 // Get the map of the receiver and compute the hash. 239 // Get the map of the receiver and compute the hash.
194 __ mov(scratch, FieldOperand(name, String::kHashFieldOffset)); 240 __ mov(scratch, FieldOperand(name, String::kHashFieldOffset));
195 __ add(scratch, FieldOperand(receiver, HeapObject::kMapOffset)); 241 __ add(scratch, FieldOperand(receiver, HeapObject::kMapOffset));
196 __ xor_(scratch, flags); 242 __ xor_(scratch, flags);
197 __ and_(scratch, (kPrimaryTableSize - 1) << kHeapObjectTagSize); 243 __ and_(scratch, (kPrimaryTableSize - 1) << kHeapObjectTagSize);
198 244
199 // Probe the primary table. 245 // Probe the primary table.
200 ProbeTable(isolate, masm, flags, kPrimary, name, scratch, extra); 246 ProbeTable(isolate(), masm, flags, kPrimary, name, scratch, extra);
201 247
202 // Primary miss: Compute hash for secondary probe. 248 // Primary miss: Compute hash for secondary probe.
203 __ mov(scratch, FieldOperand(name, String::kHashFieldOffset)); 249 __ mov(scratch, FieldOperand(name, String::kHashFieldOffset));
204 __ add(scratch, FieldOperand(receiver, HeapObject::kMapOffset)); 250 __ add(scratch, FieldOperand(receiver, HeapObject::kMapOffset));
205 __ xor_(scratch, flags); 251 __ xor_(scratch, flags);
206 __ and_(scratch, (kPrimaryTableSize - 1) << kHeapObjectTagSize); 252 __ and_(scratch, (kPrimaryTableSize - 1) << kHeapObjectTagSize);
207 __ sub(scratch, name); 253 __ sub(scratch, name);
208 __ add(scratch, Immediate(flags)); 254 __ add(scratch, Immediate(flags));
209 __ and_(scratch, (kSecondaryTableSize - 1) << kHeapObjectTagSize); 255 __ and_(scratch, (kSecondaryTableSize - 1) << kHeapObjectTagSize);
210 256
211 // Probe the secondary table. 257 // Probe the secondary table.
212 ProbeTable(isolate, masm, flags, kSecondary, name, scratch, extra); 258 ProbeTable(isolate(), masm, flags, kSecondary, name, scratch, extra);
213 259
214 // Cache miss: Fall-through and let caller handle the miss by 260 // Cache miss: Fall-through and let caller handle the miss by
215 // entering the runtime system. 261 // entering the runtime system.
216 __ bind(&miss); 262 __ bind(&miss);
217 } 263 }
218 264
219 265
220 void StubCompiler::GenerateLoadGlobalFunctionPrototype(MacroAssembler* masm, 266 void StubCompiler::GenerateLoadGlobalFunctionPrototype(MacroAssembler* masm,
221 int index, 267 int index,
222 Register prototype) { 268 Register prototype) {
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after
320 __ TryGetFunctionPrototype(receiver, scratch1, scratch2, miss_label); 366 __ TryGetFunctionPrototype(receiver, scratch1, scratch2, miss_label);
321 __ mov(eax, scratch1); 367 __ mov(eax, scratch1);
322 __ ret(0); 368 __ ret(0);
323 } 369 }
324 370
325 371
326 // Load a fast property out of a holder object (src). In-object properties 372 // Load a fast property out of a holder object (src). In-object properties
327 // are loaded directly otherwise the property is loaded from the properties 373 // are loaded directly otherwise the property is loaded from the properties
328 // fixed array. 374 // fixed array.
329 void StubCompiler::GenerateFastPropertyLoad(MacroAssembler* masm, 375 void StubCompiler::GenerateFastPropertyLoad(MacroAssembler* masm,
330 Register dst, Register src, 376 Register dst,
331 JSObject* holder, int index) { 377 Register src,
378 Handle<JSObject> holder,
379 int index) {
332 // Adjust for the number of properties stored in the holder. 380 // Adjust for the number of properties stored in the holder.
333 index -= holder->map()->inobject_properties(); 381 index -= holder->map()->inobject_properties();
334 if (index < 0) { 382 if (index < 0) {
335 // Get the property straight out of the holder. 383 // Get the property straight out of the holder.
336 int offset = holder->map()->instance_size() + (index * kPointerSize); 384 int offset = holder->map()->instance_size() + (index * kPointerSize);
337 __ mov(dst, FieldOperand(src, offset)); 385 __ mov(dst, FieldOperand(src, offset));
338 } else { 386 } else {
339 // Calculate the offset into the properties array. 387 // Calculate the offset into the properties array.
340 int offset = index * kPointerSize + FixedArray::kHeaderSize; 388 int offset = index * kPointerSize + FixedArray::kHeaderSize;
341 __ mov(dst, FieldOperand(src, JSObject::kPropertiesOffset)); 389 __ mov(dst, FieldOperand(src, JSObject::kPropertiesOffset));
(...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after
479 return masm->TryCallApiFunctionAndReturn(&fun, 527 return masm->TryCallApiFunctionAndReturn(&fun,
480 argc + kFastApiCallArguments + 1); 528 argc + kFastApiCallArguments + 1);
481 } 529 }
482 530
483 531
484 class CallInterceptorCompiler BASE_EMBEDDED { 532 class CallInterceptorCompiler BASE_EMBEDDED {
485 public: 533 public:
486 CallInterceptorCompiler(StubCompiler* stub_compiler, 534 CallInterceptorCompiler(StubCompiler* stub_compiler,
487 const ParameterCount& arguments, 535 const ParameterCount& arguments,
488 Register name, 536 Register name,
489 Code::ExtraICState extra_ic_state) 537 Code::ExtraICState extra_state)
490 : stub_compiler_(stub_compiler), 538 : stub_compiler_(stub_compiler),
491 arguments_(arguments), 539 arguments_(arguments),
492 name_(name), 540 name_(name),
493 extra_ic_state_(extra_ic_state) {} 541 extra_state_(extra_state) {}
494 542
495 MaybeObject* Compile(MacroAssembler* masm, 543 MaybeObject* Compile(MacroAssembler* masm,
496 JSObject* object, 544 JSObject* object,
497 JSObject* holder, 545 JSObject* holder,
498 String* name, 546 String* name,
499 LookupResult* lookup, 547 LookupResult* lookup,
500 Register receiver, 548 Register receiver,
501 Register scratch1, 549 Register scratch1,
502 Register scratch2, 550 Register scratch2,
503 Register scratch3, 551 Register scratch3,
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after
607 // by the previous CheckPrototypes. 655 // by the previous CheckPrototypes.
608 ASSERT(depth2 == kInvalidProtoDepth); 656 ASSERT(depth2 == kInvalidProtoDepth);
609 } 657 }
610 658
611 // Invoke function. 659 // Invoke function.
612 if (can_do_fast_api_call) { 660 if (can_do_fast_api_call) {
613 MaybeObject* result = 661 MaybeObject* result =
614 GenerateFastApiCall(masm, optimization, arguments_.immediate()); 662 GenerateFastApiCall(masm, optimization, arguments_.immediate());
615 if (result->IsFailure()) return result; 663 if (result->IsFailure()) return result;
616 } else { 664 } else {
617 CallKind call_kind = CallICBase::Contextual::decode(extra_ic_state_) 665 CallKind call_kind = CallICBase::Contextual::decode(extra_state_)
618 ? CALL_AS_FUNCTION 666 ? CALL_AS_FUNCTION
619 : CALL_AS_METHOD; 667 : CALL_AS_METHOD;
620 __ InvokeFunction(optimization.constant_function(), arguments_, 668 __ InvokeFunction(optimization.constant_function(), arguments_,
621 JUMP_FUNCTION, NullCallWrapper(), call_kind); 669 JUMP_FUNCTION, NullCallWrapper(), call_kind);
622 } 670 }
623 671
624 // Deferred code for fast API call case---clean preallocated space. 672 // Deferred code for fast API call case---clean preallocated space.
625 if (can_do_fast_api_call) { 673 if (can_do_fast_api_call) {
626 __ bind(&miss_cleanup); 674 __ bind(&miss_cleanup);
627 FreeSpaceForFastApiCall(masm, scratch1); 675 FreeSpaceForFastApiCall(masm, scratch1);
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
693 // Leave the internal frame. 741 // Leave the internal frame.
694 } 742 }
695 743
696 __ cmp(eax, masm->isolate()->factory()->no_interceptor_result_sentinel()); 744 __ cmp(eax, masm->isolate()->factory()->no_interceptor_result_sentinel());
697 __ j(not_equal, interceptor_succeeded); 745 __ j(not_equal, interceptor_succeeded);
698 } 746 }
699 747
700 StubCompiler* stub_compiler_; 748 StubCompiler* stub_compiler_;
701 const ParameterCount& arguments_; 749 const ParameterCount& arguments_;
702 Register name_; 750 Register name_;
703 Code::ExtraICState extra_ic_state_; 751 Code::ExtraICState extra_state_;
704 }; 752 };
705 753
706 754
707 void StubCompiler::GenerateLoadMiss(MacroAssembler* masm, Code::Kind kind) { 755 void StubCompiler::GenerateLoadMiss(MacroAssembler* masm, Code::Kind kind) {
708 ASSERT(kind == Code::LOAD_IC || kind == Code::KEYED_LOAD_IC); 756 ASSERT(kind == Code::LOAD_IC || kind == Code::KEYED_LOAD_IC);
709 Code* code = NULL; 757 Handle<Code> code = (kind == Code::LOAD_IC)
710 if (kind == Code::LOAD_IC) { 758 ? masm->isolate()->builtins()->LoadIC_Miss()
711 code = masm->isolate()->builtins()->builtin(Builtins::kLoadIC_Miss); 759 : masm->isolate()->builtins()->KeyedLoadIC_Miss();
712 } else { 760 __ jmp(code, RelocInfo::CODE_TARGET);
713 code = masm->isolate()->builtins()->builtin(Builtins::kKeyedLoadIC_Miss);
714 }
715
716 Handle<Code> ic(code);
717 __ jmp(ic, RelocInfo::CODE_TARGET);
718 } 761 }
719 762
720 763
721 void StubCompiler::GenerateKeyedLoadMissForceGeneric(MacroAssembler* masm) { 764 void StubCompiler::GenerateKeyedLoadMissForceGeneric(MacroAssembler* masm) {
722 Code* code = masm->isolate()->builtins()->builtin( 765 Code* code = masm->isolate()->builtins()->builtin(
723 Builtins::kKeyedLoadIC_MissForceGeneric); 766 Builtins::kKeyedLoadIC_MissForceGeneric);
724 Handle<Code> ic(code); 767 Handle<Code> ic(code);
725 __ jmp(ic, RelocInfo::CODE_TARGET); 768 __ jmp(ic, RelocInfo::CODE_TARGET);
726 } 769 }
727 770
728 771
729 // Both name_reg and receiver_reg are preserved on jumps to miss_label, 772 // Both name_reg and receiver_reg are preserved on jumps to miss_label,
730 // but may be destroyed if store is successful. 773 // but may be destroyed if store is successful.
731 void StubCompiler::GenerateStoreField(MacroAssembler* masm, 774 void StubCompiler::GenerateStoreField(MacroAssembler* masm,
732 JSObject* object, 775 Handle<JSObject> object,
733 int index, 776 int index,
734 Map* transition, 777 Handle<Map> transition,
735 Register receiver_reg, 778 Register receiver_reg,
736 Register name_reg, 779 Register name_reg,
737 Register scratch, 780 Register scratch,
738 Label* miss_label) { 781 Label* miss_label) {
739 // Check that the object isn't a smi. 782 // Check that the object isn't a smi.
740 __ JumpIfSmi(receiver_reg, miss_label); 783 __ JumpIfSmi(receiver_reg, miss_label);
741 784
742 // Check that the map of the object hasn't changed. 785 // Check that the map of the object hasn't changed.
743 __ cmp(FieldOperand(receiver_reg, HeapObject::kMapOffset), 786 __ cmp(FieldOperand(receiver_reg, HeapObject::kMapOffset),
744 Immediate(Handle<Map>(object->map()))); 787 Immediate(Handle<Map>(object->map())));
745 __ j(not_equal, miss_label); 788 __ j(not_equal, miss_label);
746 789
747 // Perform global security token check if needed. 790 // Perform global security token check if needed.
748 if (object->IsJSGlobalProxy()) { 791 if (object->IsJSGlobalProxy()) {
749 __ CheckAccessGlobalProxy(receiver_reg, scratch, miss_label); 792 __ CheckAccessGlobalProxy(receiver_reg, scratch, miss_label);
750 } 793 }
751 794
752 // Stub never generated for non-global objects that require access 795 // Stub never generated for non-global objects that require access
753 // checks. 796 // checks.
754 ASSERT(object->IsJSGlobalProxy() || !object->IsAccessCheckNeeded()); 797 ASSERT(object->IsJSGlobalProxy() || !object->IsAccessCheckNeeded());
755 798
756 // Perform map transition for the receiver if necessary. 799 // Perform map transition for the receiver if necessary.
757 if ((transition != NULL) && (object->map()->unused_property_fields() == 0)) { 800 if (!transition.is_null() && (object->map()->unused_property_fields() == 0)) {
758 // The properties must be extended before we can store the value. 801 // The properties must be extended before we can store the value.
759 // We jump to a runtime call that extends the properties array. 802 // We jump to a runtime call that extends the properties array.
760 __ pop(scratch); // Return address. 803 __ pop(scratch); // Return address.
761 __ push(receiver_reg); 804 __ push(receiver_reg);
762 __ push(Immediate(Handle<Map>(transition))); 805 __ push(Immediate(transition));
763 __ push(eax); 806 __ push(eax);
764 __ push(scratch); 807 __ push(scratch);
765 __ TailCallExternalReference( 808 __ TailCallExternalReference(
766 ExternalReference(IC_Utility(IC::kSharedStoreIC_ExtendStorage), 809 ExternalReference(IC_Utility(IC::kSharedStoreIC_ExtendStorage),
767 masm->isolate()), 810 masm->isolate()),
768 3, 811 3,
769 1); 812 1);
770 return; 813 return;
771 } 814 }
772 815
773 if (transition != NULL) { 816 if (!transition.is_null()) {
774 // Update the map of the object; no write barrier updating is 817 // Update the map of the object; no write barrier updating is
775 // needed because the map is never in new space. 818 // needed because the map is never in new space.
776 __ mov(FieldOperand(receiver_reg, HeapObject::kMapOffset), 819 __ mov(FieldOperand(receiver_reg, HeapObject::kMapOffset),
777 Immediate(Handle<Map>(transition))); 820 Immediate(transition));
778 } 821 }
779 822
780 // Adjust for the number of properties stored in the object. Even in the 823 // Adjust for the number of properties stored in the object. Even in the
781 // face of a transition we can use the old map here because the size of the 824 // face of a transition we can use the old map here because the size of the
782 // object and the number of in-object properties is not going to change. 825 // object and the number of in-object properties is not going to change.
783 index -= object->map()->inobject_properties(); 826 index -= object->map()->inobject_properties();
784 827
785 if (index < 0) { 828 if (index < 0) {
786 // Set the property straight into the object. 829 // Set the property straight into the object.
787 int offset = object->map()->instance_size() + (index * kPointerSize); 830 int offset = object->map()->instance_size() + (index * kPointerSize);
(...skipping 25 matching lines...) Expand all
813 } 856 }
814 857
815 // Return the value (register eax). 858 // Return the value (register eax).
816 __ ret(0); 859 __ ret(0);
817 } 860 }
818 861
819 862
820 // Generate code to check that a global property cell is empty. Create 863 // Generate code to check that a global property cell is empty. Create
821 // the property cell at compilation time if no cell exists for the 864 // the property cell at compilation time if no cell exists for the
822 // property. 865 // property.
823 MUST_USE_RESULT static MaybeObject* GenerateCheckPropertyCell( 866 static void GenerateCheckPropertyCell(MacroAssembler* masm,
867 Handle<GlobalObject> global,
868 Handle<String> name,
869 Register scratch,
870 Label* miss) {
871 Handle<JSGlobalPropertyCell> cell =
872 GlobalObject::EnsurePropertyCell(global, name);
873 ASSERT(cell->value()->IsTheHole());
874 Handle<Oddball> the_hole = masm->isolate()->factory()->the_hole_value();
875 if (Serializer::enabled()) {
876 __ mov(scratch, Immediate(cell));
877 __ cmp(FieldOperand(scratch, JSGlobalPropertyCell::kValueOffset),
878 Immediate(the_hole));
879 } else {
880 __ cmp(Operand::Cell(cell), Immediate(the_hole));
881 }
882 __ j(not_equal, miss);
883 }
884
885
886 // TODO(kmillikin): Eliminate this function when the stub cache is fully
887 // handlified.
888 MUST_USE_RESULT static MaybeObject* TryGenerateCheckPropertyCell(
824 MacroAssembler* masm, 889 MacroAssembler* masm,
825 GlobalObject* global, 890 GlobalObject* global,
826 String* name, 891 String* name,
827 Register scratch, 892 Register scratch,
828 Label* miss) { 893 Label* miss) {
829 Object* probe; 894 Object* probe;
830 { MaybeObject* maybe_probe = global->EnsurePropertyCell(name); 895 { MaybeObject* maybe_probe = global->EnsurePropertyCell(name);
831 if (!maybe_probe->ToObject(&probe)) return maybe_probe; 896 if (!maybe_probe->ToObject(&probe)) return maybe_probe;
832 } 897 }
833 JSGlobalPropertyCell* cell = JSGlobalPropertyCell::cast(probe); 898 JSGlobalPropertyCell* cell = JSGlobalPropertyCell::cast(probe);
834 ASSERT(cell->value()->IsTheHole()); 899 ASSERT(cell->value()->IsTheHole());
835 if (Serializer::enabled()) { 900 if (Serializer::enabled()) {
836 __ mov(scratch, Immediate(Handle<Object>(cell))); 901 __ mov(scratch, Immediate(Handle<Object>(cell)));
837 __ cmp(FieldOperand(scratch, JSGlobalPropertyCell::kValueOffset), 902 __ cmp(FieldOperand(scratch, JSGlobalPropertyCell::kValueOffset),
838 Immediate(masm->isolate()->factory()->the_hole_value())); 903 Immediate(masm->isolate()->factory()->the_hole_value()));
839 } else { 904 } else {
840 __ cmp(Operand::Cell(Handle<JSGlobalPropertyCell>(cell)), 905 __ cmp(Operand::Cell(Handle<JSGlobalPropertyCell>(cell)),
841 Immediate(masm->isolate()->factory()->the_hole_value())); 906 Immediate(masm->isolate()->factory()->the_hole_value()));
842 } 907 }
843 __ j(not_equal, miss); 908 __ j(not_equal, miss);
844 return cell; 909 return cell;
845 } 910 }
846 911
847 912
848 // Calls GenerateCheckPropertyCell for each global object in the prototype chain 913 // Calls GenerateCheckPropertyCell for each global object in the prototype chain
849 // from object to (but not including) holder. 914 // from object to (but not including) holder.
850 MUST_USE_RESULT static MaybeObject* GenerateCheckPropertyCells( 915 static void GenerateCheckPropertyCells(MacroAssembler* masm,
916 Handle<JSObject> object,
917 Handle<JSObject> holder,
918 Handle<String> name,
919 Register scratch,
920 Label* miss) {
921 Handle<JSObject> current = object;
922 while (!current.is_identical_to(holder)) {
923 if (current->IsGlobalObject()) {
924 GenerateCheckPropertyCell(masm,
925 Handle<GlobalObject>::cast(current),
926 name,
927 scratch,
928 miss);
929 }
930 current = Handle<JSObject>(JSObject::cast(current->GetPrototype()));
931 }
932 }
933
934
935 // TODO(kmillikin): Eliminate this function when the stub cache is fully
936 // handlified.
937 MUST_USE_RESULT static MaybeObject* TryGenerateCheckPropertyCells(
851 MacroAssembler* masm, 938 MacroAssembler* masm,
852 JSObject* object, 939 JSObject* object,
853 JSObject* holder, 940 JSObject* holder,
854 String* name, 941 String* name,
855 Register scratch, 942 Register scratch,
856 Label* miss) { 943 Label* miss) {
857 JSObject* current = object; 944 JSObject* current = object;
858 while (current != holder) { 945 while (current != holder) {
859 if (current->IsGlobalObject()) { 946 if (current->IsGlobalObject()) {
860 // Returns a cell or a failure. 947 // Returns a cell or a failure.
861 MaybeObject* result = GenerateCheckPropertyCell( 948 MaybeObject* result = TryGenerateCheckPropertyCell(
862 masm, 949 masm,
863 GlobalObject::cast(current), 950 GlobalObject::cast(current),
864 name, 951 name,
865 scratch, 952 scratch,
866 miss); 953 miss);
867 if (result->IsFailure()) return result; 954 if (result->IsFailure()) return result;
868 } 955 }
869 ASSERT(current->IsJSObject()); 956 ASSERT(current->IsJSObject());
870 current = JSObject::cast(current->GetPrototype()); 957 current = JSObject::cast(current->GetPrototype());
871 } 958 }
872 return NULL; 959 return NULL;
873 } 960 }
874 961
875 962
876 #undef __ 963 #undef __
877 #define __ ACCESS_MASM(masm()) 964 #define __ ACCESS_MASM(masm())
878 965
879 966
967 Register StubCompiler::CheckPrototypes(Handle<JSObject> object,
968 Register object_reg,
969 Handle<JSObject> holder,
970 Register holder_reg,
971 Register scratch1,
972 Register scratch2,
973 Handle<String> name,
974 int save_at_depth,
975 Label* miss) {
976 // Make sure there's no overlap between holder and object registers.
977 ASSERT(!scratch1.is(object_reg) && !scratch1.is(holder_reg));
978 ASSERT(!scratch2.is(object_reg) && !scratch2.is(holder_reg)
979 && !scratch2.is(scratch1));
980
981 // Keep track of the current object in register reg.
982 Register reg = object_reg;
983 Handle<JSObject> current = object;
984 int depth = 0;
985
986 if (save_at_depth == depth) {
987 __ mov(Operand(esp, kPointerSize), reg);
988 }
989
990 // Traverse the prototype chain and check the maps in the prototype chain for
991 // fast and global objects or do negative lookup for normal objects.
992 while (!current.is_identical_to(holder)) {
993 ++depth;
994
995 // Only global objects and objects that do not require access
996 // checks are allowed in stubs.
997 ASSERT(current->IsJSGlobalProxy() || !current->IsAccessCheckNeeded());
998
999 Handle<JSObject> prototype(JSObject::cast(current->GetPrototype()));
1000 if (!current->HasFastProperties() &&
1001 !current->IsJSGlobalObject() &&
1002 !current->IsJSGlobalProxy()) {
1003 if (!name->IsSymbol()) {
1004 name = factory()->LookupSymbol(name);
1005 }
1006 ASSERT(current->property_dictionary()->FindEntry(*name) ==
1007 StringDictionary::kNotFound);
1008
1009 GenerateDictionaryNegativeLookup(masm(), miss, reg, name,
1010 scratch1, scratch2);
1011
1012 __ mov(scratch1, FieldOperand(reg, HeapObject::kMapOffset));
1013 reg = holder_reg; // From now on the object will be in holder_reg.
1014 __ mov(reg, FieldOperand(scratch1, Map::kPrototypeOffset));
1015 } else {
1016 bool in_new_space = heap()->InNewSpace(*prototype);
1017 Handle<Map> current_map(current->map());
1018 if (in_new_space) {
1019 // Save the map in scratch1 for later.
1020 __ mov(scratch1, FieldOperand(reg, HeapObject::kMapOffset));
1021 __ cmp(scratch1, Immediate(current_map));
1022 } else {
1023 __ cmp(FieldOperand(reg, HeapObject::kMapOffset),
1024 Immediate(current_map));
1025 }
1026 // Branch on the result of the map check.
1027 __ j(not_equal, miss);
1028 // Check access rights to the global object. This has to happen after
1029 // the map check so that we know that the object is actually a global
1030 // object.
1031 if (current->IsJSGlobalProxy()) {
1032 __ CheckAccessGlobalProxy(reg, scratch2, miss);
1033 }
1034 reg = holder_reg; // From now on the object will be in holder_reg.
1035
1036 if (in_new_space) {
1037 // The prototype is in new space; we cannot store a reference to it
1038 // in the code. Load it from the map.
1039 __ mov(reg, FieldOperand(scratch1, Map::kPrototypeOffset));
1040 } else {
1041 // The prototype is in old space; load it directly.
1042 __ mov(reg, prototype);
1043 }
1044 }
1045
1046 if (save_at_depth == depth) {
1047 __ mov(Operand(esp, kPointerSize), reg);
1048 }
1049
1050 // Go to the next object in the prototype chain.
1051 current = prototype;
1052 }
1053 ASSERT(current.is_identical_to(holder));
1054
1055 // Log the check depth.
1056 LOG(isolate(), IntEvent("check-maps-depth", depth + 1));
1057
1058 // Check the holder map.
1059 __ cmp(FieldOperand(reg, HeapObject::kMapOffset),
1060 Immediate(Handle<Map>(holder->map())));
1061 __ j(not_equal, miss);
1062
1063 // Perform security check for access to the global object.
1064 ASSERT(holder->IsJSGlobalProxy() || !holder->IsAccessCheckNeeded());
1065 if (holder->IsJSGlobalProxy()) {
1066 __ CheckAccessGlobalProxy(reg, scratch1, miss);
1067 }
1068
1069 // If we've skipped any global objects, it's not enough to verify that
1070 // their maps haven't changed. We also need to check that the property
1071 // cell for the property is still empty.
1072 GenerateCheckPropertyCells(masm(), object, holder, name, scratch1, miss);
1073
1074 // Return the register containing the holder.
1075 return reg;
1076 }
1077
1078
1079 // TODO(kmillikin): Eliminate this function when the stub cache is fully
1080 // handlified.
880 Register StubCompiler::CheckPrototypes(JSObject* object, 1081 Register StubCompiler::CheckPrototypes(JSObject* object,
881 Register object_reg, 1082 Register object_reg,
882 JSObject* holder, 1083 JSObject* holder,
883 Register holder_reg, 1084 Register holder_reg,
884 Register scratch1, 1085 Register scratch1,
885 Register scratch2, 1086 Register scratch2,
886 String* name, 1087 String* name,
887 int save_at_depth, 1088 int save_at_depth,
888 Label* miss) { 1089 Label* miss) {
889 // Make sure there's no overlap between holder and object registers. 1090 // Make sure there's no overlap between holder and object registers.
(...skipping 29 matching lines...) Expand all
919 Object* lookup_result = NULL; // Initialization to please compiler. 1120 Object* lookup_result = NULL; // Initialization to please compiler.
920 if (!maybe_lookup_result->ToObject(&lookup_result)) { 1121 if (!maybe_lookup_result->ToObject(&lookup_result)) {
921 set_failure(Failure::cast(maybe_lookup_result)); 1122 set_failure(Failure::cast(maybe_lookup_result));
922 return reg; 1123 return reg;
923 } 1124 }
924 name = String::cast(lookup_result); 1125 name = String::cast(lookup_result);
925 } 1126 }
926 ASSERT(current->property_dictionary()->FindEntry(name) == 1127 ASSERT(current->property_dictionary()->FindEntry(name) ==
927 StringDictionary::kNotFound); 1128 StringDictionary::kNotFound);
928 1129
929 MaybeObject* negative_lookup = GenerateDictionaryNegativeLookup(masm(), 1130 MaybeObject* negative_lookup =
930 miss, 1131 TryGenerateDictionaryNegativeLookup(masm(), miss, reg, name,
931 reg, 1132 scratch1, scratch2);
932 name,
933 scratch1,
934 scratch2);
935 if (negative_lookup->IsFailure()) { 1133 if (negative_lookup->IsFailure()) {
936 set_failure(Failure::cast(negative_lookup)); 1134 set_failure(Failure::cast(negative_lookup));
937 return reg; 1135 return reg;
938 } 1136 }
939 1137
940 __ mov(scratch1, FieldOperand(reg, HeapObject::kMapOffset)); 1138 __ mov(scratch1, FieldOperand(reg, HeapObject::kMapOffset));
941 reg = holder_reg; // from now the object is in holder_reg 1139 reg = holder_reg; // from now the object is in holder_reg
942 __ mov(reg, FieldOperand(scratch1, Map::kPrototypeOffset)); 1140 __ mov(reg, FieldOperand(scratch1, Map::kPrototypeOffset));
943 } else if (heap()->InNewSpace(prototype)) { 1141 } else if (heap()->InNewSpace(prototype)) {
944 // Get the map of the current object. 1142 // Get the map of the current object.
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
991 1189
992 // Check the holder map. 1190 // Check the holder map.
993 __ cmp(FieldOperand(reg, HeapObject::kMapOffset), 1191 __ cmp(FieldOperand(reg, HeapObject::kMapOffset),
994 Immediate(Handle<Map>(holder->map()))); 1192 Immediate(Handle<Map>(holder->map())));
995 __ j(not_equal, miss); 1193 __ j(not_equal, miss);
996 1194
997 // Perform security check for access to the global object. 1195 // Perform security check for access to the global object.
998 ASSERT(holder->IsJSGlobalProxy() || !holder->IsAccessCheckNeeded()); 1196 ASSERT(holder->IsJSGlobalProxy() || !holder->IsAccessCheckNeeded());
999 if (holder->IsJSGlobalProxy()) { 1197 if (holder->IsJSGlobalProxy()) {
1000 __ CheckAccessGlobalProxy(reg, scratch1, miss); 1198 __ CheckAccessGlobalProxy(reg, scratch1, miss);
1001 }; 1199 }
1002 1200
1003 // If we've skipped any global objects, it's not enough to verify 1201 // If we've skipped any global objects, it's not enough to verify
1004 // that their maps haven't changed. We also need to check that the 1202 // that their maps haven't changed. We also need to check that the
1005 // property cell for the property is still empty. 1203 // property cell for the property is still empty.
1006 MaybeObject* result = GenerateCheckPropertyCells(masm(), 1204 MaybeObject* result = TryGenerateCheckPropertyCells(masm(),
1007 object, 1205 object,
1008 holder, 1206 holder,
1009 name, 1207 name,
1010 scratch1, 1208 scratch1,
1011 miss); 1209 miss);
1012 if (result->IsFailure()) set_failure(Failure::cast(result)); 1210 if (result->IsFailure()) set_failure(Failure::cast(result));
1013 1211
1014 // Return the register containing the holder. 1212 // Return the register containing the holder.
1015 return reg; 1213 return reg;
1016 } 1214 }
1017 1215
1018 1216
1019 void StubCompiler::GenerateLoadField(JSObject* object, 1217 void StubCompiler::GenerateLoadField(Handle<JSObject> object,
1020 JSObject* holder, 1218 Handle<JSObject> holder,
1021 Register receiver, 1219 Register receiver,
1022 Register scratch1, 1220 Register scratch1,
1023 Register scratch2, 1221 Register scratch2,
1024 Register scratch3, 1222 Register scratch3,
1025 int index, 1223 int index,
1026 String* name, 1224 Handle<String> name,
1027 Label* miss) { 1225 Label* miss) {
1028 // Check that the receiver isn't a smi. 1226 // Check that the receiver isn't a smi.
1029 __ JumpIfSmi(receiver, miss); 1227 __ JumpIfSmi(receiver, miss);
1030 1228
1031 // Check the prototype chain. 1229 // Check the prototype chain.
1032 Register reg = 1230 Register reg = CheckPrototypes(
1033 CheckPrototypes(object, receiver, holder, 1231 object, receiver, holder, scratch1, scratch2, scratch3, name, miss);
1034 scratch1, scratch2, scratch3, name, miss);
1035 1232
1036 // Get the value from the properties. 1233 // Get the value from the properties.
1037 GenerateFastPropertyLoad(masm(), eax, reg, holder, index); 1234 GenerateFastPropertyLoad(masm(), eax, reg, holder, index);
1038 __ ret(0); 1235 __ ret(0);
1039 } 1236 }
1040 1237
1041 1238
1042 MaybeObject* StubCompiler::GenerateLoadCallback(JSObject* object, 1239 MaybeObject* StubCompiler::GenerateLoadCallback(JSObject* object,
1043 JSObject* holder, 1240 JSObject* holder,
1044 Register receiver, 1241 Register receiver,
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
1099 __ mov(ApiParameterOperand(1), ebx); // arguments pointer. 1296 __ mov(ApiParameterOperand(1), ebx); // arguments pointer.
1100 1297
1101 // Emitting a stub call may try to allocate (if the code is not 1298 // Emitting a stub call may try to allocate (if the code is not
1102 // already generated). Do not allow the assembler to perform a 1299 // already generated). Do not allow the assembler to perform a
1103 // garbage collection but instead return the allocation failure 1300 // garbage collection but instead return the allocation failure
1104 // object. 1301 // object.
1105 return masm()->TryCallApiFunctionAndReturn(&fun, kStackSpace); 1302 return masm()->TryCallApiFunctionAndReturn(&fun, kStackSpace);
1106 } 1303 }
1107 1304
1108 1305
1109 void StubCompiler::GenerateLoadConstant(JSObject* object, 1306 void StubCompiler::GenerateLoadConstant(Handle<JSObject> object,
1110 JSObject* holder, 1307 Handle<JSObject> holder,
1111 Register receiver, 1308 Register receiver,
1112 Register scratch1, 1309 Register scratch1,
1113 Register scratch2, 1310 Register scratch2,
1114 Register scratch3, 1311 Register scratch3,
1115 Object* value, 1312 Handle<Object> value,
1116 String* name, 1313 Handle<String> name,
1117 Label* miss) { 1314 Label* miss) {
1118 // Check that the receiver isn't a smi. 1315 // Check that the receiver isn't a smi.
1119 __ JumpIfSmi(receiver, miss); 1316 __ JumpIfSmi(receiver, miss);
1120 1317
1121 // Check that the maps haven't changed. 1318 // Check that the maps haven't changed.
1122 CheckPrototypes(object, receiver, holder, 1319 CheckPrototypes(
1123 scratch1, scratch2, scratch3, name, miss); 1320 object, receiver, holder, scratch1, scratch2, scratch3, name, miss);
1124 1321
1125 // Return the constant value. 1322 // Return the constant value.
1126 __ mov(eax, Handle<Object>(value)); 1323 __ mov(eax, value);
1127 __ ret(0); 1324 __ ret(0);
1128 } 1325 }
1129 1326
1130 1327
1131 void StubCompiler::GenerateLoadInterceptor(JSObject* object, 1328 void StubCompiler::GenerateLoadInterceptor(JSObject* object,
1132 JSObject* interceptor_holder, 1329 JSObject* interceptor_holder,
1133 LookupResult* lookup, 1330 LookupResult* lookup,
1134 Register receiver, 1331 Register receiver,
1135 Register name_reg, 1332 Register name_reg,
1136 Register scratch1, 1333 Register scratch1,
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
1216 scratch2, 1413 scratch2,
1217 scratch3, 1414 scratch3,
1218 name, 1415 name,
1219 miss); 1416 miss);
1220 } 1417 }
1221 1418
1222 if (lookup->type() == FIELD) { 1419 if (lookup->type() == FIELD) {
1223 // We found FIELD property in prototype chain of interceptor's holder. 1420 // We found FIELD property in prototype chain of interceptor's holder.
1224 // Retrieve a field from field's holder. 1421 // Retrieve a field from field's holder.
1225 GenerateFastPropertyLoad(masm(), eax, holder_reg, 1422 GenerateFastPropertyLoad(masm(), eax, holder_reg,
1226 lookup->holder(), lookup->GetFieldIndex()); 1423 Handle<JSObject>(lookup->holder()),
1424 lookup->GetFieldIndex());
1227 __ ret(0); 1425 __ ret(0);
1228 } else { 1426 } else {
1229 // We found CALLBACKS property in prototype chain of interceptor's 1427 // We found CALLBACKS property in prototype chain of interceptor's
1230 // holder. 1428 // holder.
1231 ASSERT(lookup->type() == CALLBACKS); 1429 ASSERT(lookup->type() == CALLBACKS);
1232 ASSERT(lookup->GetCallbackObject()->IsAccessorInfo()); 1430 ASSERT(lookup->GetCallbackObject()->IsAccessorInfo());
1233 AccessorInfo* callback = AccessorInfo::cast(lookup->GetCallbackObject()); 1431 AccessorInfo* callback = AccessorInfo::cast(lookup->GetCallbackObject());
1234 ASSERT(callback != NULL); 1432 ASSERT(callback != NULL);
1235 ASSERT(callback->getter() != NULL); 1433 ASSERT(callback->getter() != NULL);
1236 1434
(...skipping 26 matching lines...) Expand all
1263 __ push(scratch2); // restore old return address 1461 __ push(scratch2); // restore old return address
1264 1462
1265 ExternalReference ref = 1463 ExternalReference ref =
1266 ExternalReference(IC_Utility(IC::kLoadPropertyWithInterceptorForLoad), 1464 ExternalReference(IC_Utility(IC::kLoadPropertyWithInterceptorForLoad),
1267 isolate()); 1465 isolate());
1268 __ TailCallExternalReference(ref, 5, 1); 1466 __ TailCallExternalReference(ref, 5, 1);
1269 } 1467 }
1270 } 1468 }
1271 1469
1272 1470
1273 void CallStubCompiler::GenerateNameCheck(String* name, Label* miss) { 1471 void CallStubCompiler::GenerateNameCheck(Handle<String> name, Label* miss) {
1274 if (kind_ == Code::KEYED_CALL_IC) { 1472 if (kind_ == Code::KEYED_CALL_IC) {
1275 __ cmp(ecx, Immediate(Handle<String>(name))); 1473 __ cmp(ecx, Immediate(name));
1276 __ j(not_equal, miss); 1474 __ j(not_equal, miss);
1277 } 1475 }
1278 } 1476 }
1279 1477
1280 1478
1281 void CallStubCompiler::GenerateGlobalReceiverCheck(JSObject* object, 1479 void CallStubCompiler::GenerateGlobalReceiverCheck(JSObject* object,
1282 JSObject* holder, 1480 JSObject* holder,
1283 String* name, 1481 String* name,
1284 Label* miss) { 1482 Label* miss) {
1285 ASSERT(holder->IsGlobalObject()); 1483 ASSERT(holder->IsGlobalObject());
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
1328 __ cmp(FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset), 1526 __ cmp(FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset),
1329 Immediate(Handle<SharedFunctionInfo>(function->shared()))); 1527 Immediate(Handle<SharedFunctionInfo>(function->shared())));
1330 __ j(not_equal, miss); 1528 __ j(not_equal, miss);
1331 } else { 1529 } else {
1332 __ cmp(edi, Immediate(Handle<JSFunction>(function))); 1530 __ cmp(edi, Immediate(Handle<JSFunction>(function)));
1333 __ j(not_equal, miss); 1531 __ j(not_equal, miss);
1334 } 1532 }
1335 } 1533 }
1336 1534
1337 1535
1338 MaybeObject* CallStubCompiler::GenerateMissBranch() { 1536 void CallStubCompiler::GenerateMissBranch() {
1339 MaybeObject* maybe_obj = 1537 Handle<Code> code =
1340 isolate()->stub_cache()->ComputeCallMiss(arguments().immediate(), 1538 isolate()->stub_cache()->ComputeCallMiss(arguments().immediate(),
1341 kind_, 1539 kind_,
1342 extra_ic_state_); 1540 extra_state_);
1541 __ jmp(code, RelocInfo::CODE_TARGET);
1542 }
1543
1544
1545 // TODO(kmillikin): Eliminate this function when the stub cache is fully
1546 // handlified.
1547 MaybeObject* CallStubCompiler::TryGenerateMissBranch() {
1548 MaybeObject* maybe_obj =
1549 isolate()->stub_cache()->TryComputeCallMiss(arguments().immediate(),
1550 kind_,
1551 extra_state_);
1343 Object* obj; 1552 Object* obj;
1344 if (!maybe_obj->ToObject(&obj)) return maybe_obj; 1553 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
1345 __ jmp(Handle<Code>(Code::cast(obj)), RelocInfo::CODE_TARGET); 1554 __ jmp(Handle<Code>(Code::cast(obj)), RelocInfo::CODE_TARGET);
1346 return obj; 1555 return obj;
1347 } 1556 }
1348 1557
1349 1558
1350 MUST_USE_RESULT MaybeObject* CallStubCompiler::CompileCallField( 1559 Handle<Code> CallStubCompiler::CompileCallField(Handle<JSObject> object,
1351 JSObject* object, 1560 Handle<JSObject> holder,
1352 JSObject* holder, 1561 int index,
1353 int index, 1562 Handle<String> name) {
1354 String* name) {
1355 // ----------- S t a t e ------------- 1563 // ----------- S t a t e -------------
1356 // -- ecx : name 1564 // -- ecx : name
1357 // -- esp[0] : return address 1565 // -- esp[0] : return address
1358 // -- esp[(argc - n) * 4] : arg[n] (zero-based) 1566 // -- esp[(argc - n) * 4] : arg[n] (zero-based)
1359 // -- ... 1567 // -- ...
1360 // -- esp[(argc + 1) * 4] : receiver 1568 // -- esp[(argc + 1) * 4] : receiver
1361 // ----------------------------------- 1569 // -----------------------------------
1362 Label miss; 1570 Label miss;
1363 1571
1364 GenerateNameCheck(name, &miss); 1572 GenerateNameCheck(name, &miss);
(...skipping 17 matching lines...) Expand all
1382 __ j(not_equal, &miss); 1590 __ j(not_equal, &miss);
1383 1591
1384 // Patch the receiver on the stack with the global proxy if 1592 // Patch the receiver on the stack with the global proxy if
1385 // necessary. 1593 // necessary.
1386 if (object->IsGlobalObject()) { 1594 if (object->IsGlobalObject()) {
1387 __ mov(edx, FieldOperand(edx, GlobalObject::kGlobalReceiverOffset)); 1595 __ mov(edx, FieldOperand(edx, GlobalObject::kGlobalReceiverOffset));
1388 __ mov(Operand(esp, (argc + 1) * kPointerSize), edx); 1596 __ mov(Operand(esp, (argc + 1) * kPointerSize), edx);
1389 } 1597 }
1390 1598
1391 // Invoke the function. 1599 // Invoke the function.
1392 CallKind call_kind = CallICBase::Contextual::decode(extra_ic_state_) 1600 CallKind call_kind = CallICBase::Contextual::decode(extra_state_)
1393 ? CALL_AS_FUNCTION 1601 ? CALL_AS_FUNCTION
1394 : CALL_AS_METHOD; 1602 : CALL_AS_METHOD;
1395 __ InvokeFunction(edi, arguments(), JUMP_FUNCTION, 1603 __ InvokeFunction(edi, arguments(), JUMP_FUNCTION,
1396 NullCallWrapper(), call_kind); 1604 NullCallWrapper(), call_kind);
1397 1605
1398 // Handle call cache miss. 1606 // Handle call cache miss.
1399 __ bind(&miss); 1607 __ bind(&miss);
1400 MaybeObject* maybe_result = GenerateMissBranch(); 1608 GenerateMissBranch();
1401 if (maybe_result->IsFailure()) return maybe_result;
1402 1609
1403 // Return the generated code. 1610 // Return the generated code.
1404 return GetCode(FIELD, name); 1611 return GetCode(FIELD, name);
1405 } 1612 }
1406 1613
1407 1614
1408 MaybeObject* CallStubCompiler::CompileArrayPushCall(Object* object, 1615 MaybeObject* CallStubCompiler::CompileArrayPushCall(Object* object,
1409 JSObject* holder, 1616 JSObject* holder,
1410 JSGlobalPropertyCell* cell, 1617 JSGlobalPropertyCell* cell,
1411 JSFunction* function, 1618 JSFunction* function,
1412 String* name) { 1619 String* name) {
1413 // ----------- S t a t e ------------- 1620 // ----------- S t a t e -------------
1414 // -- ecx : name 1621 // -- ecx : name
1415 // -- esp[0] : return address 1622 // -- esp[0] : return address
1416 // -- esp[(argc - n) * 4] : arg[n] (zero-based) 1623 // -- esp[(argc - n) * 4] : arg[n] (zero-based)
1417 // -- ... 1624 // -- ...
1418 // -- esp[(argc + 1) * 4] : receiver 1625 // -- esp[(argc + 1) * 4] : receiver
1419 // ----------------------------------- 1626 // -----------------------------------
1420 1627
1421 // If object is not an array, bail out to regular call. 1628 // If object is not an array, bail out to regular call.
1422 if (!object->IsJSArray() || cell != NULL) { 1629 if (!object->IsJSArray() || cell != NULL) {
1423 return isolate()->heap()->undefined_value(); 1630 return isolate()->heap()->undefined_value();
1424 } 1631 }
1425 1632
1426 Label miss; 1633 Label miss;
1427 1634
1428 GenerateNameCheck(name, &miss); 1635 GenerateNameCheck(Handle<String>(name), &miss);
1429 1636
1430 // Get the receiver from the stack. 1637 // Get the receiver from the stack.
1431 const int argc = arguments().immediate(); 1638 const int argc = arguments().immediate();
1432 __ mov(edx, Operand(esp, (argc + 1) * kPointerSize)); 1639 __ mov(edx, Operand(esp, (argc + 1) * kPointerSize));
1433 1640
1434 // Check that the receiver isn't a smi. 1641 // Check that the receiver isn't a smi.
1435 __ JumpIfSmi(edx, &miss); 1642 __ JumpIfSmi(edx, &miss);
1436 1643
1437 CheckPrototypes(JSObject::cast(object), edx, 1644 CheckPrototypes(JSObject::cast(object), edx,
1438 holder, ebx, 1645 holder, ebx,
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
1506 __ bind(&attempt_to_grow_elements); 1713 __ bind(&attempt_to_grow_elements);
1507 if (!FLAG_inline_new) { 1714 if (!FLAG_inline_new) {
1508 __ jmp(&call_builtin); 1715 __ jmp(&call_builtin);
1509 } 1716 }
1510 1717
1511 __ mov(edi, Operand(esp, argc * kPointerSize)); 1718 __ mov(edi, Operand(esp, argc * kPointerSize));
1512 // Growing elements that are SMI-only requires special handling in case 1719 // Growing elements that are SMI-only requires special handling in case
1513 // the new element is non-Smi. For now, delegate to the builtin. 1720 // the new element is non-Smi. For now, delegate to the builtin.
1514 Label no_fast_elements_check; 1721 Label no_fast_elements_check;
1515 __ JumpIfSmi(edi, &no_fast_elements_check); 1722 __ JumpIfSmi(edi, &no_fast_elements_check);
1516 __ mov(esi, FieldOperand(edx, HeapObject::kMapOffset)); 1723 __ mov(ecx, FieldOperand(edx, HeapObject::kMapOffset));
1517 __ CheckFastObjectElements(esi, &call_builtin, Label::kFar); 1724 __ CheckFastObjectElements(ecx, &call_builtin, Label::kFar);
1518 __ bind(&no_fast_elements_check); 1725 __ bind(&no_fast_elements_check);
1519 1726
1520 // We could be lucky and the elements array could be at the top of 1727 // We could be lucky and the elements array could be at the top of
1521 // new-space. In this case we can just grow it in place by moving the 1728 // new-space. In this case we can just grow it in place by moving the
1522 // allocation pointer up. 1729 // allocation pointer up.
1523 1730
1524 ExternalReference new_space_allocation_top = 1731 ExternalReference new_space_allocation_top =
1525 ExternalReference::new_space_allocation_top_address(isolate()); 1732 ExternalReference::new_space_allocation_top_address(isolate());
1526 ExternalReference new_space_allocation_limit = 1733 ExternalReference new_space_allocation_limit =
1527 ExternalReference::new_space_allocation_limit_address(isolate()); 1734 ExternalReference::new_space_allocation_limit_address(isolate());
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
1575 } 1782 }
1576 1783
1577 __ bind(&call_builtin); 1784 __ bind(&call_builtin);
1578 __ TailCallExternalReference( 1785 __ TailCallExternalReference(
1579 ExternalReference(Builtins::c_ArrayPush, isolate()), 1786 ExternalReference(Builtins::c_ArrayPush, isolate()),
1580 argc + 1, 1787 argc + 1,
1581 1); 1788 1);
1582 } 1789 }
1583 1790
1584 __ bind(&miss); 1791 __ bind(&miss);
1585 MaybeObject* maybe_result = GenerateMissBranch(); 1792 MaybeObject* maybe_result = TryGenerateMissBranch();
1586 if (maybe_result->IsFailure()) return maybe_result; 1793 if (maybe_result->IsFailure()) return maybe_result;
1587 1794
1588 // Return the generated code. 1795 // Return the generated code.
1589 return GetCode(function); 1796 return TryGetCode(function);
1590 } 1797 }
1591 1798
1592 1799
1593 MaybeObject* CallStubCompiler::CompileArrayPopCall(Object* object, 1800 MaybeObject* CallStubCompiler::CompileArrayPopCall(Object* object,
1594 JSObject* holder, 1801 JSObject* holder,
1595 JSGlobalPropertyCell* cell, 1802 JSGlobalPropertyCell* cell,
1596 JSFunction* function, 1803 JSFunction* function,
1597 String* name) { 1804 String* name) {
1598 // ----------- S t a t e ------------- 1805 // ----------- S t a t e -------------
1599 // -- ecx : name 1806 // -- ecx : name
1600 // -- esp[0] : return address 1807 // -- esp[0] : return address
1601 // -- esp[(argc - n) * 4] : arg[n] (zero-based) 1808 // -- esp[(argc - n) * 4] : arg[n] (zero-based)
1602 // -- ... 1809 // -- ...
1603 // -- esp[(argc + 1) * 4] : receiver 1810 // -- esp[(argc + 1) * 4] : receiver
1604 // ----------------------------------- 1811 // -----------------------------------
1605 1812
1606 // If object is not an array, bail out to regular call. 1813 // If object is not an array, bail out to regular call.
1607 if (!object->IsJSArray() || cell != NULL) { 1814 if (!object->IsJSArray() || cell != NULL) {
1608 return heap()->undefined_value(); 1815 return heap()->undefined_value();
1609 } 1816 }
1610 1817
1611 Label miss, return_undefined, call_builtin; 1818 Label miss, return_undefined, call_builtin;
1612 1819
1613 GenerateNameCheck(name, &miss); 1820 GenerateNameCheck(Handle<String>(name), &miss);
1614 1821
1615 // Get the receiver from the stack. 1822 // Get the receiver from the stack.
1616 const int argc = arguments().immediate(); 1823 const int argc = arguments().immediate();
1617 __ mov(edx, Operand(esp, (argc + 1) * kPointerSize)); 1824 __ mov(edx, Operand(esp, (argc + 1) * kPointerSize));
1618 1825
1619 // Check that the receiver isn't a smi. 1826 // Check that the receiver isn't a smi.
1620 __ JumpIfSmi(edx, &miss); 1827 __ JumpIfSmi(edx, &miss);
1621 CheckPrototypes(JSObject::cast(object), edx, 1828 CheckPrototypes(JSObject::cast(object), edx,
1622 holder, ebx, 1829 holder, ebx,
1623 eax, edi, name, &miss); 1830 eax, edi, name, &miss);
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
1658 __ mov(eax, Immediate(factory()->undefined_value())); 1865 __ mov(eax, Immediate(factory()->undefined_value()));
1659 __ ret((argc + 1) * kPointerSize); 1866 __ ret((argc + 1) * kPointerSize);
1660 1867
1661 __ bind(&call_builtin); 1868 __ bind(&call_builtin);
1662 __ TailCallExternalReference( 1869 __ TailCallExternalReference(
1663 ExternalReference(Builtins::c_ArrayPop, isolate()), 1870 ExternalReference(Builtins::c_ArrayPop, isolate()),
1664 argc + 1, 1871 argc + 1,
1665 1); 1872 1);
1666 1873
1667 __ bind(&miss); 1874 __ bind(&miss);
1668 MaybeObject* maybe_result = GenerateMissBranch(); 1875 MaybeObject* maybe_result = TryGenerateMissBranch();
1669 if (maybe_result->IsFailure()) return maybe_result; 1876 if (maybe_result->IsFailure()) return maybe_result;
1670 1877
1671 // Return the generated code. 1878 // Return the generated code.
1672 return GetCode(function); 1879 return TryGetCode(function);
1673 } 1880 }
1674 1881
1675 1882
1676 MaybeObject* CallStubCompiler::CompileStringCharCodeAtCall( 1883 MaybeObject* CallStubCompiler::CompileStringCharCodeAtCall(
1677 Object* object, 1884 Object* object,
1678 JSObject* holder, 1885 JSObject* holder,
1679 JSGlobalPropertyCell* cell, 1886 JSGlobalPropertyCell* cell,
1680 JSFunction* function, 1887 JSFunction* function,
1681 String* name) { 1888 String* name) {
1682 // ----------- S t a t e ------------- 1889 // ----------- S t a t e -------------
(...skipping 10 matching lines...) Expand all
1693 } 1900 }
1694 1901
1695 const int argc = arguments().immediate(); 1902 const int argc = arguments().immediate();
1696 1903
1697 Label miss; 1904 Label miss;
1698 Label name_miss; 1905 Label name_miss;
1699 Label index_out_of_range; 1906 Label index_out_of_range;
1700 Label* index_out_of_range_label = &index_out_of_range; 1907 Label* index_out_of_range_label = &index_out_of_range;
1701 1908
1702 if (kind_ == Code::CALL_IC && 1909 if (kind_ == Code::CALL_IC &&
1703 (CallICBase::StringStubState::decode(extra_ic_state_) == 1910 (CallICBase::StringStubState::decode(extra_state_) ==
1704 DEFAULT_STRING_STUB)) { 1911 DEFAULT_STRING_STUB)) {
1705 index_out_of_range_label = &miss; 1912 index_out_of_range_label = &miss;
1706 } 1913 }
1707 1914
1708 GenerateNameCheck(name, &name_miss); 1915 GenerateNameCheck(Handle<String>(name), &name_miss);
1709 1916
1710 // Check that the maps starting from the prototype haven't changed. 1917 // Check that the maps starting from the prototype haven't changed.
1711 GenerateDirectLoadGlobalFunctionPrototype(masm(), 1918 GenerateDirectLoadGlobalFunctionPrototype(masm(),
1712 Context::STRING_FUNCTION_INDEX, 1919 Context::STRING_FUNCTION_INDEX,
1713 eax, 1920 eax,
1714 &miss); 1921 &miss);
1715 ASSERT(object != holder); 1922 ASSERT(object != holder);
1716 CheckPrototypes(JSObject::cast(object->GetPrototype()), eax, holder, 1923 CheckPrototypes(JSObject::cast(object->GetPrototype()), eax, holder,
1717 ebx, edx, edi, name, &miss); 1924 ebx, edx, edi, name, &miss);
1718 1925
(...skipping 25 matching lines...) Expand all
1744 if (index_out_of_range.is_linked()) { 1951 if (index_out_of_range.is_linked()) {
1745 __ bind(&index_out_of_range); 1952 __ bind(&index_out_of_range);
1746 __ Set(eax, Immediate(factory()->nan_value())); 1953 __ Set(eax, Immediate(factory()->nan_value()));
1747 __ ret((argc + 1) * kPointerSize); 1954 __ ret((argc + 1) * kPointerSize);
1748 } 1955 }
1749 1956
1750 __ bind(&miss); 1957 __ bind(&miss);
1751 // Restore function name in ecx. 1958 // Restore function name in ecx.
1752 __ Set(ecx, Immediate(Handle<String>(name))); 1959 __ Set(ecx, Immediate(Handle<String>(name)));
1753 __ bind(&name_miss); 1960 __ bind(&name_miss);
1754 MaybeObject* maybe_result = GenerateMissBranch(); 1961 MaybeObject* maybe_result = TryGenerateMissBranch();
1755 if (maybe_result->IsFailure()) return maybe_result; 1962 if (maybe_result->IsFailure()) return maybe_result;
1756 1963
1757 // Return the generated code. 1964 // Return the generated code.
1758 return GetCode(function); 1965 return TryGetCode(function);
1759 } 1966 }
1760 1967
1761 1968
1762 MaybeObject* CallStubCompiler::CompileStringCharAtCall( 1969 MaybeObject* CallStubCompiler::CompileStringCharAtCall(
1763 Object* object, 1970 Object* object,
1764 JSObject* holder, 1971 JSObject* holder,
1765 JSGlobalPropertyCell* cell, 1972 JSGlobalPropertyCell* cell,
1766 JSFunction* function, 1973 JSFunction* function,
1767 String* name) { 1974 String* name) {
1768 // ----------- S t a t e ------------- 1975 // ----------- S t a t e -------------
(...skipping 10 matching lines...) Expand all
1779 } 1986 }
1780 1987
1781 const int argc = arguments().immediate(); 1988 const int argc = arguments().immediate();
1782 1989
1783 Label miss; 1990 Label miss;
1784 Label name_miss; 1991 Label name_miss;
1785 Label index_out_of_range; 1992 Label index_out_of_range;
1786 Label* index_out_of_range_label = &index_out_of_range; 1993 Label* index_out_of_range_label = &index_out_of_range;
1787 1994
1788 if (kind_ == Code::CALL_IC && 1995 if (kind_ == Code::CALL_IC &&
1789 (CallICBase::StringStubState::decode(extra_ic_state_) == 1996 (CallICBase::StringStubState::decode(extra_state_) ==
1790 DEFAULT_STRING_STUB)) { 1997 DEFAULT_STRING_STUB)) {
1791 index_out_of_range_label = &miss; 1998 index_out_of_range_label = &miss;
1792 } 1999 }
1793 2000
1794 GenerateNameCheck(name, &name_miss); 2001 GenerateNameCheck(Handle<String>(name), &name_miss);
1795 2002
1796 // Check that the maps starting from the prototype haven't changed. 2003 // Check that the maps starting from the prototype haven't changed.
1797 GenerateDirectLoadGlobalFunctionPrototype(masm(), 2004 GenerateDirectLoadGlobalFunctionPrototype(masm(),
1798 Context::STRING_FUNCTION_INDEX, 2005 Context::STRING_FUNCTION_INDEX,
1799 eax, 2006 eax,
1800 &miss); 2007 &miss);
1801 ASSERT(object != holder); 2008 ASSERT(object != holder);
1802 CheckPrototypes(JSObject::cast(object->GetPrototype()), eax, holder, 2009 CheckPrototypes(JSObject::cast(object->GetPrototype()), eax, holder,
1803 ebx, edx, edi, name, &miss); 2010 ebx, edx, edi, name, &miss);
1804 2011
(...skipping 27 matching lines...) Expand all
1832 if (index_out_of_range.is_linked()) { 2039 if (index_out_of_range.is_linked()) {
1833 __ bind(&index_out_of_range); 2040 __ bind(&index_out_of_range);
1834 __ Set(eax, Immediate(factory()->empty_string())); 2041 __ Set(eax, Immediate(factory()->empty_string()));
1835 __ ret((argc + 1) * kPointerSize); 2042 __ ret((argc + 1) * kPointerSize);
1836 } 2043 }
1837 2044
1838 __ bind(&miss); 2045 __ bind(&miss);
1839 // Restore function name in ecx. 2046 // Restore function name in ecx.
1840 __ Set(ecx, Immediate(Handle<String>(name))); 2047 __ Set(ecx, Immediate(Handle<String>(name)));
1841 __ bind(&name_miss); 2048 __ bind(&name_miss);
1842 MaybeObject* maybe_result = GenerateMissBranch(); 2049 MaybeObject* maybe_result = TryGenerateMissBranch();
1843 if (maybe_result->IsFailure()) return maybe_result; 2050 if (maybe_result->IsFailure()) return maybe_result;
1844 2051
1845 // Return the generated code. 2052 // Return the generated code.
1846 return GetCode(function); 2053 return TryGetCode(function);
1847 } 2054 }
1848 2055
1849 2056
1850 MaybeObject* CallStubCompiler::CompileStringFromCharCodeCall( 2057 MaybeObject* CallStubCompiler::CompileStringFromCharCodeCall(
1851 Object* object, 2058 Object* object,
1852 JSObject* holder, 2059 JSObject* holder,
1853 JSGlobalPropertyCell* cell, 2060 JSGlobalPropertyCell* cell,
1854 JSFunction* function, 2061 JSFunction* function,
1855 String* name) { 2062 String* name) {
1856 // ----------- S t a t e ------------- 2063 // ----------- S t a t e -------------
1857 // -- ecx : function name 2064 // -- ecx : function name
1858 // -- esp[0] : return address 2065 // -- esp[0] : return address
1859 // -- esp[(argc - n) * 4] : arg[n] (zero-based) 2066 // -- esp[(argc - n) * 4] : arg[n] (zero-based)
1860 // -- ... 2067 // -- ...
1861 // -- esp[(argc + 1) * 4] : receiver 2068 // -- esp[(argc + 1) * 4] : receiver
1862 // ----------------------------------- 2069 // -----------------------------------
1863 2070
1864 const int argc = arguments().immediate(); 2071 const int argc = arguments().immediate();
1865 2072
1866 // If the object is not a JSObject or we got an unexpected number of 2073 // If the object is not a JSObject or we got an unexpected number of
1867 // arguments, bail out to the regular call. 2074 // arguments, bail out to the regular call.
1868 if (!object->IsJSObject() || argc != 1) { 2075 if (!object->IsJSObject() || argc != 1) {
1869 return isolate()->heap()->undefined_value(); 2076 return isolate()->heap()->undefined_value();
1870 } 2077 }
1871 2078
1872 Label miss; 2079 Label miss;
1873 GenerateNameCheck(name, &miss); 2080 GenerateNameCheck(Handle<String>(name), &miss);
1874 2081
1875 if (cell == NULL) { 2082 if (cell == NULL) {
1876 __ mov(edx, Operand(esp, 2 * kPointerSize)); 2083 __ mov(edx, Operand(esp, 2 * kPointerSize));
1877 2084
1878 STATIC_ASSERT(kSmiTag == 0); 2085 STATIC_ASSERT(kSmiTag == 0);
1879 __ JumpIfSmi(edx, &miss); 2086 __ JumpIfSmi(edx, &miss);
1880 2087
1881 CheckPrototypes(JSObject::cast(object), edx, holder, ebx, eax, edi, name, 2088 CheckPrototypes(JSObject::cast(object), edx, holder, ebx, eax, edi, name,
1882 &miss); 2089 &miss);
1883 } else { 2090 } else {
(...skipping 17 matching lines...) Expand all
1901 StringCharFromCodeGenerator char_from_code_generator(code, eax); 2108 StringCharFromCodeGenerator char_from_code_generator(code, eax);
1902 char_from_code_generator.GenerateFast(masm()); 2109 char_from_code_generator.GenerateFast(masm());
1903 __ ret(2 * kPointerSize); 2110 __ ret(2 * kPointerSize);
1904 2111
1905 StubRuntimeCallHelper call_helper; 2112 StubRuntimeCallHelper call_helper;
1906 char_from_code_generator.GenerateSlow(masm(), call_helper); 2113 char_from_code_generator.GenerateSlow(masm(), call_helper);
1907 2114
1908 // Tail call the full function. We do not have to patch the receiver 2115 // Tail call the full function. We do not have to patch the receiver
1909 // because the function makes no use of it. 2116 // because the function makes no use of it.
1910 __ bind(&slow); 2117 __ bind(&slow);
1911 CallKind call_kind = CallICBase::Contextual::decode(extra_ic_state_) 2118 CallKind call_kind = CallICBase::Contextual::decode(extra_state_)
1912 ? CALL_AS_FUNCTION 2119 ? CALL_AS_FUNCTION
1913 : CALL_AS_METHOD; 2120 : CALL_AS_METHOD;
1914 __ InvokeFunction(function, arguments(), JUMP_FUNCTION, 2121 __ InvokeFunction(function, arguments(), JUMP_FUNCTION,
1915 NullCallWrapper(), call_kind); 2122 NullCallWrapper(), call_kind);
1916 2123
1917 __ bind(&miss); 2124 __ bind(&miss);
1918 // ecx: function name. 2125 // ecx: function name.
1919 MaybeObject* maybe_result = GenerateMissBranch(); 2126 MaybeObject* maybe_result = TryGenerateMissBranch();
1920 if (maybe_result->IsFailure()) return maybe_result; 2127 if (maybe_result->IsFailure()) return maybe_result;
1921 2128
1922 // Return the generated code. 2129 // Return the generated code.
1923 return (cell == NULL) ? GetCode(function) : GetCode(NORMAL, name); 2130 return (cell == NULL) ? TryGetCode(function) : TryGetCode(NORMAL, name);
1924 } 2131 }
1925 2132
1926 2133
1927 MaybeObject* CallStubCompiler::CompileMathFloorCall(Object* object, 2134 MaybeObject* CallStubCompiler::CompileMathFloorCall(Object* object,
1928 JSObject* holder, 2135 JSObject* holder,
1929 JSGlobalPropertyCell* cell, 2136 JSGlobalPropertyCell* cell,
1930 JSFunction* function, 2137 JSFunction* function,
1931 String* name) { 2138 String* name) {
1932 // ----------- S t a t e ------------- 2139 // ----------- S t a t e -------------
1933 // -- ecx : name 2140 // -- ecx : name
(...skipping 11 matching lines...) Expand all
1945 2152
1946 const int argc = arguments().immediate(); 2153 const int argc = arguments().immediate();
1947 2154
1948 // If the object is not a JSObject or we got an unexpected number of 2155 // If the object is not a JSObject or we got an unexpected number of
1949 // arguments, bail out to the regular call. 2156 // arguments, bail out to the regular call.
1950 if (!object->IsJSObject() || argc != 1) { 2157 if (!object->IsJSObject() || argc != 1) {
1951 return isolate()->heap()->undefined_value(); 2158 return isolate()->heap()->undefined_value();
1952 } 2159 }
1953 2160
1954 Label miss; 2161 Label miss;
1955 GenerateNameCheck(name, &miss); 2162 GenerateNameCheck(Handle<String>(name), &miss);
1956 2163
1957 if (cell == NULL) { 2164 if (cell == NULL) {
1958 __ mov(edx, Operand(esp, 2 * kPointerSize)); 2165 __ mov(edx, Operand(esp, 2 * kPointerSize));
1959 2166
1960 STATIC_ASSERT(kSmiTag == 0); 2167 STATIC_ASSERT(kSmiTag == 0);
1961 __ JumpIfSmi(edx, &miss); 2168 __ JumpIfSmi(edx, &miss);
1962 2169
1963 CheckPrototypes(JSObject::cast(object), edx, holder, ebx, eax, edi, name, 2170 CheckPrototypes(JSObject::cast(object), edx, holder, ebx, eax, edi, name,
1964 &miss); 2171 &miss);
1965 } else { 2172 } else {
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
2038 __ ret(2 * kPointerSize); 2245 __ ret(2 * kPointerSize);
2039 2246
2040 // Tail call the full function. We do not have to patch the receiver 2247 // Tail call the full function. We do not have to patch the receiver
2041 // because the function makes no use of it. 2248 // because the function makes no use of it.
2042 __ bind(&slow); 2249 __ bind(&slow);
2043 __ InvokeFunction(function, arguments(), JUMP_FUNCTION, 2250 __ InvokeFunction(function, arguments(), JUMP_FUNCTION,
2044 NullCallWrapper(), CALL_AS_METHOD); 2251 NullCallWrapper(), CALL_AS_METHOD);
2045 2252
2046 __ bind(&miss); 2253 __ bind(&miss);
2047 // ecx: function name. 2254 // ecx: function name.
2048 MaybeObject* maybe_result = GenerateMissBranch(); 2255 MaybeObject* maybe_result = TryGenerateMissBranch();
2049 if (maybe_result->IsFailure()) return maybe_result; 2256 if (maybe_result->IsFailure()) return maybe_result;
2050 2257
2051 // Return the generated code. 2258 // Return the generated code.
2052 return (cell == NULL) ? GetCode(function) : GetCode(NORMAL, name); 2259 return (cell == NULL) ? TryGetCode(function) : TryGetCode(NORMAL, name);
2053 } 2260 }
2054 2261
2055 2262
2056 MaybeObject* CallStubCompiler::CompileMathAbsCall(Object* object, 2263 MaybeObject* CallStubCompiler::CompileMathAbsCall(Object* object,
2057 JSObject* holder, 2264 JSObject* holder,
2058 JSGlobalPropertyCell* cell, 2265 JSGlobalPropertyCell* cell,
2059 JSFunction* function, 2266 JSFunction* function,
2060 String* name) { 2267 String* name) {
2061 // ----------- S t a t e ------------- 2268 // ----------- S t a t e -------------
2062 // -- ecx : name 2269 // -- ecx : name
2063 // -- esp[0] : return address 2270 // -- esp[0] : return address
2064 // -- esp[(argc - n) * 4] : arg[n] (zero-based) 2271 // -- esp[(argc - n) * 4] : arg[n] (zero-based)
2065 // -- ... 2272 // -- ...
2066 // -- esp[(argc + 1) * 4] : receiver 2273 // -- esp[(argc + 1) * 4] : receiver
2067 // ----------------------------------- 2274 // -----------------------------------
2068 2275
2069 const int argc = arguments().immediate(); 2276 const int argc = arguments().immediate();
2070 2277
2071 // If the object is not a JSObject or we got an unexpected number of 2278 // If the object is not a JSObject or we got an unexpected number of
2072 // arguments, bail out to the regular call. 2279 // arguments, bail out to the regular call.
2073 if (!object->IsJSObject() || argc != 1) { 2280 if (!object->IsJSObject() || argc != 1) {
2074 return isolate()->heap()->undefined_value(); 2281 return isolate()->heap()->undefined_value();
2075 } 2282 }
2076 2283
2077 Label miss; 2284 Label miss;
2078 GenerateNameCheck(name, &miss); 2285 GenerateNameCheck(Handle<String>(name), &miss);
2079 2286
2080 if (cell == NULL) { 2287 if (cell == NULL) {
2081 __ mov(edx, Operand(esp, 2 * kPointerSize)); 2288 __ mov(edx, Operand(esp, 2 * kPointerSize));
2082 2289
2083 STATIC_ASSERT(kSmiTag == 0); 2290 STATIC_ASSERT(kSmiTag == 0);
2084 __ JumpIfSmi(edx, &miss); 2291 __ JumpIfSmi(edx, &miss);
2085 2292
2086 CheckPrototypes(JSObject::cast(object), edx, holder, ebx, eax, edi, name, 2293 CheckPrototypes(JSObject::cast(object), edx, holder, ebx, eax, edi, name,
2087 &miss); 2294 &miss);
2088 } else { 2295 } else {
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
2142 __ ret(2 * kPointerSize); 2349 __ ret(2 * kPointerSize);
2143 2350
2144 // Tail call the full function. We do not have to patch the receiver 2351 // Tail call the full function. We do not have to patch the receiver
2145 // because the function makes no use of it. 2352 // because the function makes no use of it.
2146 __ bind(&slow); 2353 __ bind(&slow);
2147 __ InvokeFunction(function, arguments(), JUMP_FUNCTION, 2354 __ InvokeFunction(function, arguments(), JUMP_FUNCTION,
2148 NullCallWrapper(), CALL_AS_METHOD); 2355 NullCallWrapper(), CALL_AS_METHOD);
2149 2356
2150 __ bind(&miss); 2357 __ bind(&miss);
2151 // ecx: function name. 2358 // ecx: function name.
2152 MaybeObject* maybe_result = GenerateMissBranch(); 2359 MaybeObject* maybe_result = TryGenerateMissBranch();
2153 if (maybe_result->IsFailure()) return maybe_result; 2360 if (maybe_result->IsFailure()) return maybe_result;
2154 2361
2155 // Return the generated code. 2362 // Return the generated code.
2156 return (cell == NULL) ? GetCode(function) : GetCode(NORMAL, name); 2363 return (cell == NULL) ? TryGetCode(function) : TryGetCode(NORMAL, name);
2157 } 2364 }
2158 2365
2159 2366
2160 MaybeObject* CallStubCompiler::CompileFastApiCall( 2367 MaybeObject* CallStubCompiler::CompileFastApiCall(
2161 const CallOptimization& optimization, 2368 const CallOptimization& optimization,
2162 Object* object, 2369 Object* object,
2163 JSObject* holder, 2370 JSObject* holder,
2164 JSGlobalPropertyCell* cell, 2371 JSGlobalPropertyCell* cell,
2165 JSFunction* function, 2372 JSFunction* function,
2166 String* name) { 2373 String* name) {
2167 ASSERT(optimization.is_simple_api_call()); 2374 ASSERT(optimization.is_simple_api_call());
2168 // Bail out if object is a global object as we don't want to 2375 // Bail out if object is a global object as we don't want to
2169 // repatch it to global receiver. 2376 // repatch it to global receiver.
2170 if (object->IsGlobalObject()) return heap()->undefined_value(); 2377 if (object->IsGlobalObject()) return heap()->undefined_value();
2171 if (cell != NULL) return heap()->undefined_value(); 2378 if (cell != NULL) return heap()->undefined_value();
2172 if (!object->IsJSObject()) return heap()->undefined_value(); 2379 if (!object->IsJSObject()) return heap()->undefined_value();
2173 int depth = optimization.GetPrototypeDepthOfExpectedType( 2380 int depth = optimization.GetPrototypeDepthOfExpectedType(
2174 JSObject::cast(object), holder); 2381 JSObject::cast(object), holder);
2175 if (depth == kInvalidProtoDepth) return heap()->undefined_value(); 2382 if (depth == kInvalidProtoDepth) return heap()->undefined_value();
2176 2383
2177 Label miss, miss_before_stack_reserved; 2384 Label miss, miss_before_stack_reserved;
2178 2385
2179 GenerateNameCheck(name, &miss_before_stack_reserved); 2386 GenerateNameCheck(Handle<String>(name), &miss_before_stack_reserved);
2180 2387
2181 // Get the receiver from the stack. 2388 // Get the receiver from the stack.
2182 const int argc = arguments().immediate(); 2389 const int argc = arguments().immediate();
2183 __ mov(edx, Operand(esp, (argc + 1) * kPointerSize)); 2390 __ mov(edx, Operand(esp, (argc + 1) * kPointerSize));
2184 2391
2185 // Check that the receiver isn't a smi. 2392 // Check that the receiver isn't a smi.
2186 __ JumpIfSmi(edx, &miss_before_stack_reserved); 2393 __ JumpIfSmi(edx, &miss_before_stack_reserved);
2187 2394
2188 Counters* counters = isolate()->counters(); 2395 Counters* counters = isolate()->counters();
2189 __ IncrementCounter(counters->call_const(), 1); 2396 __ IncrementCounter(counters->call_const(), 1);
(...skipping 13 matching lines...) Expand all
2203 2410
2204 // esp[2 * kPointerSize] is uninitialized, esp[3 * kPointerSize] contains 2411 // esp[2 * kPointerSize] is uninitialized, esp[3 * kPointerSize] contains
2205 // duplicate of return address and will be overwritten. 2412 // duplicate of return address and will be overwritten.
2206 MaybeObject* result = GenerateFastApiCall(masm(), optimization, argc); 2413 MaybeObject* result = GenerateFastApiCall(masm(), optimization, argc);
2207 if (result->IsFailure()) return result; 2414 if (result->IsFailure()) return result;
2208 2415
2209 __ bind(&miss); 2416 __ bind(&miss);
2210 __ add(esp, Immediate(kFastApiCallArguments * kPointerSize)); 2417 __ add(esp, Immediate(kFastApiCallArguments * kPointerSize));
2211 2418
2212 __ bind(&miss_before_stack_reserved); 2419 __ bind(&miss_before_stack_reserved);
2213 MaybeObject* maybe_result = GenerateMissBranch(); 2420 MaybeObject* maybe_result = TryGenerateMissBranch();
2214 if (maybe_result->IsFailure()) return maybe_result; 2421 if (maybe_result->IsFailure()) return maybe_result;
2215 2422
2216 // Return the generated code. 2423 // Return the generated code.
2217 return GetCode(function); 2424 return TryGetCode(function);
2218 } 2425 }
2219 2426
2220 2427
2221 MaybeObject* CallStubCompiler::CompileCallConstant( 2428 MaybeObject* CallStubCompiler::CompileCallConstant(
2222 Object* object, 2429 Object* object,
2223 JSObject* holder, 2430 JSObject* holder,
2224 JSFunction* function, 2431 JSFunction* function,
2225 String* name, 2432 String* name,
2226 CheckType check) { 2433 CheckType check) {
2227 // ----------- S t a t e ------------- 2434 // ----------- S t a t e -------------
2228 // -- ecx : name 2435 // -- ecx : name
2229 // -- esp[0] : return address 2436 // -- esp[0] : return address
2230 // -- esp[(argc - n) * 4] : arg[n] (zero-based) 2437 // -- esp[(argc - n) * 4] : arg[n] (zero-based)
2231 // -- ... 2438 // -- ...
2232 // -- esp[(argc + 1) * 4] : receiver 2439 // -- esp[(argc + 1) * 4] : receiver
2233 // ----------------------------------- 2440 // -----------------------------------
2234 2441
2235 if (HasCustomCallGenerator(function)) { 2442 if (HasCustomCallGenerator(function)) {
2236 MaybeObject* maybe_result = CompileCustomCall( 2443 MaybeObject* maybe_result = CompileCustomCall(
2237 object, holder, NULL, function, name); 2444 object, holder, NULL, function, name);
2238 Object* result; 2445 Object* result;
2239 if (!maybe_result->ToObject(&result)) return maybe_result; 2446 if (!maybe_result->ToObject(&result)) return maybe_result;
2240 // undefined means bail out to regular compiler. 2447 // undefined means bail out to regular compiler.
2241 if (!result->IsUndefined()) return result; 2448 if (!result->IsUndefined()) return result;
2242 } 2449 }
2243 2450
2244 Label miss; 2451 Label miss;
2245 2452
2246 GenerateNameCheck(name, &miss); 2453 GenerateNameCheck(Handle<String>(name), &miss);
2247 2454
2248 // Get the receiver from the stack. 2455 // Get the receiver from the stack.
2249 const int argc = arguments().immediate(); 2456 const int argc = arguments().immediate();
2250 __ mov(edx, Operand(esp, (argc + 1) * kPointerSize)); 2457 __ mov(edx, Operand(esp, (argc + 1) * kPointerSize));
2251 2458
2252 // Check that the receiver isn't a smi. 2459 // Check that the receiver isn't a smi.
2253 if (check != NUMBER_CHECK) { 2460 if (check != NUMBER_CHECK) {
2254 __ JumpIfSmi(edx, &miss); 2461 __ JumpIfSmi(edx, &miss);
2255 } 2462 }
2256 2463
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
2332 CheckPrototypes(JSObject::cast(object->GetPrototype()), eax, holder, 2539 CheckPrototypes(JSObject::cast(object->GetPrototype()), eax, holder,
2333 ebx, edx, edi, name, &miss); 2540 ebx, edx, edi, name, &miss);
2334 } 2541 }
2335 break; 2542 break;
2336 } 2543 }
2337 2544
2338 default: 2545 default:
2339 UNREACHABLE(); 2546 UNREACHABLE();
2340 } 2547 }
2341 2548
2342 CallKind call_kind = CallICBase::Contextual::decode(extra_ic_state_) 2549 CallKind call_kind = CallICBase::Contextual::decode(extra_state_)
2343 ? CALL_AS_FUNCTION 2550 ? CALL_AS_FUNCTION
2344 : CALL_AS_METHOD; 2551 : CALL_AS_METHOD;
2345 __ InvokeFunction(function, arguments(), JUMP_FUNCTION, 2552 __ InvokeFunction(function, arguments(), JUMP_FUNCTION,
2346 NullCallWrapper(), call_kind); 2553 NullCallWrapper(), call_kind);
2347 2554
2348 // Handle call cache miss. 2555 // Handle call cache miss.
2349 __ bind(&miss); 2556 __ bind(&miss);
2350 MaybeObject* maybe_result = GenerateMissBranch(); 2557 MaybeObject* maybe_result = TryGenerateMissBranch();
2351 if (maybe_result->IsFailure()) return maybe_result; 2558 if (maybe_result->IsFailure()) return maybe_result;
2352 2559
2353 // Return the generated code. 2560 // Return the generated code.
2354 return GetCode(function); 2561 return TryGetCode(function);
2355 } 2562 }
2356 2563
2357 2564
2358 MaybeObject* CallStubCompiler::CompileCallInterceptor(JSObject* object, 2565 MaybeObject* CallStubCompiler::CompileCallInterceptor(JSObject* object,
2359 JSObject* holder, 2566 JSObject* holder,
2360 String* name) { 2567 String* name) {
2361 // ----------- S t a t e ------------- 2568 // ----------- S t a t e -------------
2362 // -- ecx : name 2569 // -- ecx : name
2363 // -- esp[0] : return address 2570 // -- esp[0] : return address
2364 // -- esp[(argc - n) * 4] : arg[n] (zero-based) 2571 // -- esp[(argc - n) * 4] : arg[n] (zero-based)
2365 // -- ... 2572 // -- ...
2366 // -- esp[(argc + 1) * 4] : receiver 2573 // -- esp[(argc + 1) * 4] : receiver
2367 // ----------------------------------- 2574 // -----------------------------------
2368 Label miss; 2575 Label miss;
2369 2576
2370 GenerateNameCheck(name, &miss); 2577 GenerateNameCheck(Handle<String>(name), &miss);
2371 2578
2372 // Get the number of arguments. 2579 // Get the number of arguments.
2373 const int argc = arguments().immediate(); 2580 const int argc = arguments().immediate();
2374 2581
2375 LookupResult lookup; 2582 LookupResult lookup(isolate());
2376 LookupPostInterceptor(holder, name, &lookup); 2583 LookupPostInterceptor(holder, name, &lookup);
2377 2584
2378 // Get the receiver from the stack. 2585 // Get the receiver from the stack.
2379 __ mov(edx, Operand(esp, (argc + 1) * kPointerSize)); 2586 __ mov(edx, Operand(esp, (argc + 1) * kPointerSize));
2380 2587
2381 CallInterceptorCompiler compiler(this, arguments(), ecx, extra_ic_state_); 2588 CallInterceptorCompiler compiler(this, arguments(), ecx, extra_state_);
2382 MaybeObject* result = compiler.Compile(masm(), 2589 MaybeObject* result = compiler.Compile(masm(),
2383 object, 2590 object,
2384 holder, 2591 holder,
2385 name, 2592 name,
2386 &lookup, 2593 &lookup,
2387 edx, 2594 edx,
2388 ebx, 2595 ebx,
2389 edi, 2596 edi,
2390 eax, 2597 eax,
2391 &miss); 2598 &miss);
2392 if (result->IsFailure()) return result; 2599 if (result->IsFailure()) return result;
2393 2600
2394 // Restore receiver. 2601 // Restore receiver.
2395 __ mov(edx, Operand(esp, (argc + 1) * kPointerSize)); 2602 __ mov(edx, Operand(esp, (argc + 1) * kPointerSize));
2396 2603
2397 // Check that the function really is a function. 2604 // Check that the function really is a function.
2398 __ JumpIfSmi(eax, &miss); 2605 __ JumpIfSmi(eax, &miss);
2399 __ CmpObjectType(eax, JS_FUNCTION_TYPE, ebx); 2606 __ CmpObjectType(eax, JS_FUNCTION_TYPE, ebx);
2400 __ j(not_equal, &miss); 2607 __ j(not_equal, &miss);
2401 2608
2402 // Patch the receiver on the stack with the global proxy if 2609 // Patch the receiver on the stack with the global proxy if
2403 // necessary. 2610 // necessary.
2404 if (object->IsGlobalObject()) { 2611 if (object->IsGlobalObject()) {
2405 __ mov(edx, FieldOperand(edx, GlobalObject::kGlobalReceiverOffset)); 2612 __ mov(edx, FieldOperand(edx, GlobalObject::kGlobalReceiverOffset));
2406 __ mov(Operand(esp, (argc + 1) * kPointerSize), edx); 2613 __ mov(Operand(esp, (argc + 1) * kPointerSize), edx);
2407 } 2614 }
2408 2615
2409 // Invoke the function. 2616 // Invoke the function.
2410 __ mov(edi, eax); 2617 __ mov(edi, eax);
2411 CallKind call_kind = CallICBase::Contextual::decode(extra_ic_state_) 2618 CallKind call_kind = CallICBase::Contextual::decode(extra_state_)
2412 ? CALL_AS_FUNCTION 2619 ? CALL_AS_FUNCTION
2413 : CALL_AS_METHOD; 2620 : CALL_AS_METHOD;
2414 __ InvokeFunction(edi, arguments(), JUMP_FUNCTION, 2621 __ InvokeFunction(edi, arguments(), JUMP_FUNCTION,
2415 NullCallWrapper(), call_kind); 2622 NullCallWrapper(), call_kind);
2416 2623
2417 // Handle load cache miss. 2624 // Handle load cache miss.
2418 __ bind(&miss); 2625 __ bind(&miss);
2419 MaybeObject* maybe_result = GenerateMissBranch(); 2626 MaybeObject* maybe_result = TryGenerateMissBranch();
2420 if (maybe_result->IsFailure()) return maybe_result; 2627 if (maybe_result->IsFailure()) return maybe_result;
2421 2628
2422 // Return the generated code. 2629 // Return the generated code.
2423 return GetCode(INTERCEPTOR, name); 2630 return TryGetCode(INTERCEPTOR, name);
2424 } 2631 }
2425 2632
2426 2633
2427 MaybeObject* CallStubCompiler::CompileCallGlobal( 2634 MaybeObject* CallStubCompiler::CompileCallGlobal(
2428 JSObject* object, 2635 JSObject* object,
2429 GlobalObject* holder, 2636 GlobalObject* holder,
2430 JSGlobalPropertyCell* cell, 2637 JSGlobalPropertyCell* cell,
2431 JSFunction* function, 2638 JSFunction* function,
2432 String* name) { 2639 String* name) {
2433 // ----------- S t a t e ------------- 2640 // ----------- S t a t e -------------
2434 // -- ecx : name 2641 // -- ecx : name
2435 // -- esp[0] : return address 2642 // -- esp[0] : return address
2436 // -- esp[(argc - n) * 4] : arg[n] (zero-based) 2643 // -- esp[(argc - n) * 4] : arg[n] (zero-based)
2437 // -- ... 2644 // -- ...
2438 // -- esp[(argc + 1) * 4] : receiver 2645 // -- esp[(argc + 1) * 4] : receiver
2439 // ----------------------------------- 2646 // -----------------------------------
2440 2647
2441 if (HasCustomCallGenerator(function)) { 2648 if (HasCustomCallGenerator(function)) {
2442 MaybeObject* maybe_result = CompileCustomCall( 2649 MaybeObject* maybe_result = CompileCustomCall(
2443 object, holder, cell, function, name); 2650 object, holder, cell, function, name);
2444 Object* result; 2651 Object* result;
2445 if (!maybe_result->ToObject(&result)) return maybe_result; 2652 if (!maybe_result->ToObject(&result)) return maybe_result;
2446 // undefined means bail out to regular compiler. 2653 // undefined means bail out to regular compiler.
2447 if (!result->IsUndefined()) return result; 2654 if (!result->IsUndefined()) return result;
2448 } 2655 }
2449 2656
2450 Label miss; 2657 Label miss;
2451 2658
2452 GenerateNameCheck(name, &miss); 2659 GenerateNameCheck(Handle<String>(name), &miss);
2453 2660
2454 // Get the number of arguments. 2661 // Get the number of arguments.
2455 const int argc = arguments().immediate(); 2662 const int argc = arguments().immediate();
2456 2663
2457 GenerateGlobalReceiverCheck(object, holder, name, &miss); 2664 GenerateGlobalReceiverCheck(object, holder, name, &miss);
2458 2665
2459 GenerateLoadFunctionFromCell(cell, function, &miss); 2666 GenerateLoadFunctionFromCell(cell, function, &miss);
2460 2667
2461 // Patch the receiver on the stack with the global proxy. 2668 // Patch the receiver on the stack with the global proxy.
2462 if (object->IsGlobalObject()) { 2669 if (object->IsGlobalObject()) {
2463 __ mov(edx, FieldOperand(edx, GlobalObject::kGlobalReceiverOffset)); 2670 __ mov(edx, FieldOperand(edx, GlobalObject::kGlobalReceiverOffset));
2464 __ mov(Operand(esp, (argc + 1) * kPointerSize), edx); 2671 __ mov(Operand(esp, (argc + 1) * kPointerSize), edx);
2465 } 2672 }
2466 2673
2467 // Setup the context (function already in edi). 2674 // Setup the context (function already in edi).
2468 __ mov(esi, FieldOperand(edi, JSFunction::kContextOffset)); 2675 __ mov(esi, FieldOperand(edi, JSFunction::kContextOffset));
2469 2676
2470 // Jump to the cached code (tail call). 2677 // Jump to the cached code (tail call).
2471 Counters* counters = isolate()->counters(); 2678 Counters* counters = isolate()->counters();
2472 __ IncrementCounter(counters->call_global_inline(), 1); 2679 __ IncrementCounter(counters->call_global_inline(), 1);
2473 ASSERT(function->is_compiled());
2474 ParameterCount expected(function->shared()->formal_parameter_count()); 2680 ParameterCount expected(function->shared()->formal_parameter_count());
2475 CallKind call_kind = CallICBase::Contextual::decode(extra_ic_state_) 2681 CallKind call_kind = CallICBase::Contextual::decode(extra_state_)
2476 ? CALL_AS_FUNCTION 2682 ? CALL_AS_FUNCTION
2477 : CALL_AS_METHOD; 2683 : CALL_AS_METHOD;
2478 if (V8::UseCrankshaft()) { 2684 // We call indirectly through the code field in the function to
2479 // TODO(kasperl): For now, we always call indirectly through the 2685 // allow recompilation to take effect without changing any of the
2480 // code field in the function to allow recompilation to take effect 2686 // call sites.
2481 // without changing any of the call sites. 2687 __ InvokeCode(FieldOperand(edi, JSFunction::kCodeEntryOffset),
2482 __ InvokeCode(FieldOperand(edi, JSFunction::kCodeEntryOffset), 2688 expected, arguments(), JUMP_FUNCTION,
2483 expected, arguments(), JUMP_FUNCTION, 2689 NullCallWrapper(), call_kind);
2484 NullCallWrapper(), call_kind);
2485 } else {
2486 Handle<Code> code(function->code());
2487 __ InvokeCode(code, expected, arguments(),
2488 RelocInfo::CODE_TARGET, JUMP_FUNCTION,
2489 NullCallWrapper(), call_kind);
2490 }
2491 2690
2492 // Handle call cache miss. 2691 // Handle call cache miss.
2493 __ bind(&miss); 2692 __ bind(&miss);
2494 __ IncrementCounter(counters->call_global_inline_miss(), 1); 2693 __ IncrementCounter(counters->call_global_inline_miss(), 1);
2495 MaybeObject* maybe_result = GenerateMissBranch(); 2694 MaybeObject* maybe_result = TryGenerateMissBranch();
2496 if (maybe_result->IsFailure()) return maybe_result; 2695 if (maybe_result->IsFailure()) return maybe_result;
2497 2696
2498 // Return the generated code. 2697 // Return the generated code.
2499 return GetCode(NORMAL, name); 2698 return TryGetCode(NORMAL, name);
2500 } 2699 }
2501 2700
2502 2701
2503 MaybeObject* StoreStubCompiler::CompileStoreField(JSObject* object, 2702 Handle<Code> StoreStubCompiler::CompileStoreField(Handle<JSObject> object,
2504 int index, 2703 int index,
2505 Map* transition, 2704 Handle<Map> transition,
2506 String* name) { 2705 Handle<String> name) {
2507 // ----------- S t a t e ------------- 2706 // ----------- S t a t e -------------
2508 // -- eax : value 2707 // -- eax : value
2509 // -- ecx : name 2708 // -- ecx : name
2510 // -- edx : receiver 2709 // -- edx : receiver
2511 // -- esp[0] : return address 2710 // -- esp[0] : return address
2512 // ----------------------------------- 2711 // -----------------------------------
2513 Label miss; 2712 Label miss;
2514 2713
2515 // Generate store field code. Trashes the name register. 2714 // Generate store field code. Trashes the name register.
2516 GenerateStoreField(masm(), 2715 GenerateStoreField(masm(), object, index, transition, edx, ecx, ebx, &miss);
2517 object,
2518 index,
2519 transition,
2520 edx, ecx, ebx,
2521 &miss);
2522 2716
2523 // Handle store cache miss. 2717 // Handle store cache miss.
2524 __ bind(&miss); 2718 __ bind(&miss);
2525 __ mov(ecx, Immediate(Handle<String>(name))); // restore name 2719 __ mov(ecx, Immediate(name)); // restore name
2526 Handle<Code> ic = isolate()->builtins()->StoreIC_Miss(); 2720 Handle<Code> ic = isolate()->builtins()->StoreIC_Miss();
2527 __ jmp(ic, RelocInfo::CODE_TARGET); 2721 __ jmp(ic, RelocInfo::CODE_TARGET);
2528 2722
2529 // Return the generated code. 2723 // Return the generated code.
2530 return GetCode(transition == NULL ? FIELD : MAP_TRANSITION, name); 2724 return GetCode(transition.is_null() ? FIELD : MAP_TRANSITION, name);
2531 } 2725 }
2532 2726
2533 2727
2534 MaybeObject* StoreStubCompiler::CompileStoreCallback(JSObject* object, 2728 Handle<Code> StoreStubCompiler::CompileStoreCallback(
2535 AccessorInfo* callback, 2729 Handle<JSObject> object,
2536 String* name) { 2730 Handle<AccessorInfo> callback,
2731 Handle<String> name) {
2537 // ----------- S t a t e ------------- 2732 // ----------- S t a t e -------------
2538 // -- eax : value 2733 // -- eax : value
2539 // -- ecx : name 2734 // -- ecx : name
2540 // -- edx : receiver 2735 // -- edx : receiver
2541 // -- esp[0] : return address 2736 // -- esp[0] : return address
2542 // ----------------------------------- 2737 // -----------------------------------
2543 Label miss; 2738 Label miss;
2544 2739
2545 // Check that the object isn't a smi. 2740 // Check that the object isn't a smi.
2546 __ JumpIfSmi(edx, &miss); 2741 __ JumpIfSmi(edx, &miss);
2547 2742
2548 // Check that the map of the object hasn't changed. 2743 // Check that the map of the object hasn't changed.
2549 __ cmp(FieldOperand(edx, HeapObject::kMapOffset), 2744 __ cmp(FieldOperand(edx, HeapObject::kMapOffset),
2550 Immediate(Handle<Map>(object->map()))); 2745 Immediate(Handle<Map>(object->map())));
2551 __ j(not_equal, &miss); 2746 __ j(not_equal, &miss);
2552 2747
2553 // Perform global security token check if needed. 2748 // Perform global security token check if needed.
2554 if (object->IsJSGlobalProxy()) { 2749 if (object->IsJSGlobalProxy()) {
2555 __ CheckAccessGlobalProxy(edx, ebx, &miss); 2750 __ CheckAccessGlobalProxy(edx, ebx, &miss);
2556 } 2751 }
2557 2752
2558 // Stub never generated for non-global objects that require access 2753 // Stub never generated for non-global objects that require access
2559 // checks. 2754 // checks.
2560 ASSERT(object->IsJSGlobalProxy() || !object->IsAccessCheckNeeded()); 2755 ASSERT(object->IsJSGlobalProxy() || !object->IsAccessCheckNeeded());
2561 2756
2562 __ pop(ebx); // remove the return address 2757 __ pop(ebx); // remove the return address
2563 __ push(edx); // receiver 2758 __ push(edx); // receiver
2564 __ push(Immediate(Handle<AccessorInfo>(callback))); // callback info 2759 __ push(Immediate(callback)); // callback info
2565 __ push(ecx); // name 2760 __ push(ecx); // name
2566 __ push(eax); // value 2761 __ push(eax); // value
2567 __ push(ebx); // restore return address 2762 __ push(ebx); // restore return address
2568 2763
2569 // Do tail-call to the runtime system. 2764 // Do tail-call to the runtime system.
2570 ExternalReference store_callback_property = 2765 ExternalReference store_callback_property =
2571 ExternalReference(IC_Utility(IC::kStoreCallbackProperty), isolate()); 2766 ExternalReference(IC_Utility(IC::kStoreCallbackProperty), isolate());
2572 __ TailCallExternalReference(store_callback_property, 4, 1); 2767 __ TailCallExternalReference(store_callback_property, 4, 1);
2573 2768
2574 // Handle store cache miss. 2769 // Handle store cache miss.
2575 __ bind(&miss); 2770 __ bind(&miss);
2576 Handle<Code> ic = isolate()->builtins()->StoreIC_Miss(); 2771 Handle<Code> ic = isolate()->builtins()->StoreIC_Miss();
2577 __ jmp(ic, RelocInfo::CODE_TARGET); 2772 __ jmp(ic, RelocInfo::CODE_TARGET);
2578 2773
2579 // Return the generated code. 2774 // Return the generated code.
2580 return GetCode(CALLBACKS, name); 2775 return GetCode(CALLBACKS, name);
2581 } 2776 }
2582 2777
2583 2778
2584 MaybeObject* StoreStubCompiler::CompileStoreInterceptor(JSObject* receiver, 2779 Handle<Code> StoreStubCompiler::CompileStoreInterceptor(
2585 String* name) { 2780 Handle<JSObject> receiver,
2781 Handle<String> name) {
2586 // ----------- S t a t e ------------- 2782 // ----------- S t a t e -------------
2587 // -- eax : value 2783 // -- eax : value
2588 // -- ecx : name 2784 // -- ecx : name
2589 // -- edx : receiver 2785 // -- edx : receiver
2590 // -- esp[0] : return address 2786 // -- esp[0] : return address
2591 // ----------------------------------- 2787 // -----------------------------------
2592 Label miss; 2788 Label miss;
2593 2789
2594 // Check that the object isn't a smi. 2790 // Check that the object isn't a smi.
2595 __ JumpIfSmi(edx, &miss); 2791 __ JumpIfSmi(edx, &miss);
(...skipping 27 matching lines...) Expand all
2623 // Handle store cache miss. 2819 // Handle store cache miss.
2624 __ bind(&miss); 2820 __ bind(&miss);
2625 Handle<Code> ic = isolate()->builtins()->StoreIC_Miss(); 2821 Handle<Code> ic = isolate()->builtins()->StoreIC_Miss();
2626 __ jmp(ic, RelocInfo::CODE_TARGET); 2822 __ jmp(ic, RelocInfo::CODE_TARGET);
2627 2823
2628 // Return the generated code. 2824 // Return the generated code.
2629 return GetCode(INTERCEPTOR, name); 2825 return GetCode(INTERCEPTOR, name);
2630 } 2826 }
2631 2827
2632 2828
2633 MaybeObject* StoreStubCompiler::CompileStoreGlobal(GlobalObject* object, 2829 Handle<Code> StoreStubCompiler::CompileStoreGlobal(
2634 JSGlobalPropertyCell* cell, 2830 Handle<GlobalObject> object,
2635 String* name) { 2831 Handle<JSGlobalPropertyCell> cell,
2832 Handle<String> name) {
2636 // ----------- S t a t e ------------- 2833 // ----------- S t a t e -------------
2637 // -- eax : value 2834 // -- eax : value
2638 // -- ecx : name 2835 // -- ecx : name
2639 // -- edx : receiver 2836 // -- edx : receiver
2640 // -- esp[0] : return address 2837 // -- esp[0] : return address
2641 // ----------------------------------- 2838 // -----------------------------------
2642 Label miss; 2839 Label miss;
2643 2840
2644 // Check that the map of the global has not changed. 2841 // Check that the map of the global has not changed.
2645 __ cmp(FieldOperand(edx, HeapObject::kMapOffset), 2842 __ cmp(FieldOperand(edx, HeapObject::kMapOffset),
2646 Immediate(Handle<Map>(object->map()))); 2843 Immediate(Handle<Map>(object->map())));
2647 __ j(not_equal, &miss); 2844 __ j(not_equal, &miss);
2648 2845
2649 // Compute the cell operand to use. 2846 // Compute the cell operand to use.
2650 __ mov(ebx, Immediate(Handle<JSGlobalPropertyCell>(cell))); 2847 __ mov(ebx, Immediate(cell));
2651 Operand cell_operand = FieldOperand(ebx, JSGlobalPropertyCell::kValueOffset); 2848 Operand cell_operand = FieldOperand(ebx, JSGlobalPropertyCell::kValueOffset);
2652 2849
2653 // Check that the value in the cell is not the hole. If it is, this 2850 // Check that the value in the cell is not the hole. If it is, this
2654 // cell could have been deleted and reintroducing the global needs 2851 // cell could have been deleted and reintroducing the global needs
2655 // to update the property details in the property dictionary of the 2852 // to update the property details in the property dictionary of the
2656 // global object. We bail out to the runtime system to do that. 2853 // global object. We bail out to the runtime system to do that.
2657 __ cmp(cell_operand, factory()->the_hole_value()); 2854 __ cmp(cell_operand, factory()->the_hole_value());
2658 __ j(equal, &miss); 2855 __ j(equal, &miss);
2659 2856
2660 // Store the value in the cell. 2857 // Store the value in the cell.
(...skipping 23 matching lines...) Expand all
2684 __ bind(&miss); 2881 __ bind(&miss);
2685 __ IncrementCounter(counters->named_store_global_inline_miss(), 1); 2882 __ IncrementCounter(counters->named_store_global_inline_miss(), 1);
2686 Handle<Code> ic = isolate()->builtins()->StoreIC_Miss(); 2883 Handle<Code> ic = isolate()->builtins()->StoreIC_Miss();
2687 __ jmp(ic, RelocInfo::CODE_TARGET); 2884 __ jmp(ic, RelocInfo::CODE_TARGET);
2688 2885
2689 // Return the generated code. 2886 // Return the generated code.
2690 return GetCode(NORMAL, name); 2887 return GetCode(NORMAL, name);
2691 } 2888 }
2692 2889
2693 2890
2694 MaybeObject* KeyedStoreStubCompiler::CompileStoreField(JSObject* object, 2891 Handle<Code> KeyedStoreStubCompiler::CompileStoreField(Handle<JSObject> object,
2695 int index, 2892 int index,
2696 Map* transition, 2893 Handle<Map> transition,
2697 String* name) { 2894 Handle<String> name) {
2698 // ----------- S t a t e ------------- 2895 // ----------- S t a t e -------------
2699 // -- eax : value 2896 // -- eax : value
2700 // -- ecx : key 2897 // -- ecx : key
2701 // -- edx : receiver 2898 // -- edx : receiver
2702 // -- esp[0] : return address 2899 // -- esp[0] : return address
2703 // ----------------------------------- 2900 // -----------------------------------
2704 Label miss; 2901 Label miss;
2705 2902
2706 Counters* counters = isolate()->counters(); 2903 Counters* counters = isolate()->counters();
2707 __ IncrementCounter(counters->keyed_store_field(), 1); 2904 __ IncrementCounter(counters->keyed_store_field(), 1);
2708 2905
2709 // Check that the name has not changed. 2906 // Check that the name has not changed.
2710 __ cmp(ecx, Immediate(Handle<String>(name))); 2907 __ cmp(ecx, Immediate(name));
2711 __ j(not_equal, &miss); 2908 __ j(not_equal, &miss);
2712 2909
2713 // Generate store field code. Trashes the name register. 2910 // Generate store field code. Trashes the name register.
2714 GenerateStoreField(masm(), 2911 GenerateStoreField(masm(), object, index, transition, edx, ecx, ebx, &miss);
2715 object,
2716 index,
2717 transition,
2718 edx, ecx, ebx,
2719 &miss);
2720 2912
2721 // Handle store cache miss. 2913 // Handle store cache miss.
2722 __ bind(&miss); 2914 __ bind(&miss);
2723 __ DecrementCounter(counters->keyed_store_field(), 1); 2915 __ DecrementCounter(counters->keyed_store_field(), 1);
2724 Handle<Code> ic = isolate()->builtins()->KeyedStoreIC_Miss(); 2916 Handle<Code> ic = isolate()->builtins()->KeyedStoreIC_Miss();
2725 __ jmp(ic, RelocInfo::CODE_TARGET); 2917 __ jmp(ic, RelocInfo::CODE_TARGET);
2726 2918
2727 // Return the generated code. 2919 // Return the generated code.
2728 return GetCode(transition == NULL ? FIELD : MAP_TRANSITION, name); 2920 return GetCode(transition.is_null() ? FIELD : MAP_TRANSITION, name);
2729 } 2921 }
2730 2922
2731 2923
2732 MaybeObject* KeyedStoreStubCompiler::CompileStoreElement(Map* receiver_map) { 2924 Handle<Code> KeyedStoreStubCompiler::CompileStoreElement(
2925 Handle<Map> receiver_map) {
2733 // ----------- S t a t e ------------- 2926 // ----------- S t a t e -------------
2734 // -- eax : value 2927 // -- eax : value
2735 // -- ecx : key 2928 // -- ecx : key
2736 // -- edx : receiver 2929 // -- edx : receiver
2737 // -- esp[0] : return address 2930 // -- esp[0] : return address
2738 // ----------------------------------- 2931 // -----------------------------------
2739 Code* stub;
2740 ElementsKind elements_kind = receiver_map->elements_kind(); 2932 ElementsKind elements_kind = receiver_map->elements_kind();
2741 bool is_jsarray = receiver_map->instance_type() == JS_ARRAY_TYPE; 2933 bool is_jsarray = receiver_map->instance_type() == JS_ARRAY_TYPE;
2742 MaybeObject* maybe_stub = 2934 Handle<Code> stub =
2743 KeyedStoreElementStub(is_jsarray, elements_kind).TryGetCode(); 2935 KeyedStoreElementStub(is_jsarray, elements_kind).GetCode();
2744 if (!maybe_stub->To(&stub)) return maybe_stub; 2936
2745 __ DispatchMap(edx, 2937 __ DispatchMap(edx, receiver_map, stub, DO_SMI_CHECK);
2746 Handle<Map>(receiver_map),
2747 Handle<Code>(stub),
2748 DO_SMI_CHECK);
2749 2938
2750 Handle<Code> ic = isolate()->builtins()->KeyedStoreIC_Miss(); 2939 Handle<Code> ic = isolate()->builtins()->KeyedStoreIC_Miss();
2751 __ jmp(ic, RelocInfo::CODE_TARGET); 2940 __ jmp(ic, RelocInfo::CODE_TARGET);
2752 2941
2753 // Return the generated code. 2942 // Return the generated code.
2754 return GetCode(NORMAL, NULL); 2943 return GetCode(NORMAL, factory()->empty_string());
2755 } 2944 }
2756 2945
2757 2946
2758 MaybeObject* KeyedStoreStubCompiler::CompileStorePolymorphic( 2947 Handle<Code> KeyedStoreStubCompiler::CompileStorePolymorphic(
2759 MapList* receiver_maps, 2948 MapHandleList* receiver_maps,
2760 CodeList* handler_stubs, 2949 CodeHandleList* handler_stubs,
2761 MapList* transitioned_maps) { 2950 MapHandleList* transitioned_maps) {
2762 // ----------- S t a t e ------------- 2951 // ----------- S t a t e -------------
2763 // -- eax : value 2952 // -- eax : value
2764 // -- ecx : key 2953 // -- ecx : key
2765 // -- edx : receiver 2954 // -- edx : receiver
2766 // -- esp[0] : return address 2955 // -- esp[0] : return address
2767 // ----------------------------------- 2956 // -----------------------------------
2768 Label miss; 2957 Label miss;
2769 __ JumpIfSmi(edx, &miss, Label::kNear); 2958 __ JumpIfSmi(edx, &miss, Label::kNear);
2770 __ mov(edi, FieldOperand(edx, HeapObject::kMapOffset)); 2959 __ mov(edi, FieldOperand(edx, HeapObject::kMapOffset));
2771 // ebx: receiver->map(). 2960 // ebx: receiver->map().
2772 for (int i = 0; i < receiver_maps->length(); ++i) { 2961 for (int i = 0; i < receiver_maps->length(); ++i) {
2773 Handle<Map> map(receiver_maps->at(i)); 2962 __ cmp(edi, receiver_maps->at(i));
2774 __ cmp(edi, map); 2963 if (transitioned_maps->at(i).is_null()) {
2775 if (transitioned_maps->at(i) == NULL) { 2964 __ j(equal, handler_stubs->at(i));
2776 __ j(equal, Handle<Code>(handler_stubs->at(i)));
2777 } else { 2965 } else {
2778 Label next_map; 2966 Label next_map;
2779 __ j(not_equal, &next_map, Label::kNear); 2967 __ j(not_equal, &next_map, Label::kNear);
2780 __ mov(ebx, Immediate(Handle<Map>(transitioned_maps->at(i)))); 2968 __ mov(ebx, Immediate(transitioned_maps->at(i)));
2781 __ jmp(Handle<Code>(handler_stubs->at(i)), RelocInfo::CODE_TARGET); 2969 __ jmp(handler_stubs->at(i), RelocInfo::CODE_TARGET);
2782 __ bind(&next_map); 2970 __ bind(&next_map);
2783 } 2971 }
2784 } 2972 }
2785 __ bind(&miss); 2973 __ bind(&miss);
2786 Handle<Code> miss_ic = isolate()->builtins()->KeyedStoreIC_Miss(); 2974 Handle<Code> miss_ic = isolate()->builtins()->KeyedStoreIC_Miss();
2787 __ jmp(miss_ic, RelocInfo::CODE_TARGET); 2975 __ jmp(miss_ic, RelocInfo::CODE_TARGET);
2788 2976
2789 // Return the generated code. 2977 // Return the generated code.
2790 return GetCode(NORMAL, NULL, MEGAMORPHIC); 2978 return GetCode(NORMAL, factory()->empty_string(), MEGAMORPHIC);
2791 } 2979 }
2792 2980
2793 2981
2794 MaybeObject* LoadStubCompiler::CompileLoadNonexistent(String* name, 2982 Handle<Code> LoadStubCompiler::CompileLoadNonexistent(Handle<String> name,
2795 JSObject* object, 2983 Handle<JSObject> object,
2796 JSObject* last) { 2984 Handle<JSObject> last) {
2797 // ----------- S t a t e ------------- 2985 // ----------- S t a t e -------------
2798 // -- eax : receiver 2986 // -- eax : receiver
2799 // -- ecx : name 2987 // -- ecx : name
2800 // -- esp[0] : return address 2988 // -- esp[0] : return address
2801 // ----------------------------------- 2989 // -----------------------------------
2802 Label miss; 2990 Label miss;
2803 2991
2804 // Check that the receiver isn't a smi. 2992 // Check that the receiver isn't a smi.
2805 __ JumpIfSmi(eax, &miss); 2993 __ JumpIfSmi(eax, &miss);
2806 2994
2807 ASSERT(last->IsGlobalObject() || last->HasFastProperties()); 2995 ASSERT(last->IsGlobalObject() || last->HasFastProperties());
2808 2996
2809 // Check the maps of the full prototype chain. Also check that 2997 // Check the maps of the full prototype chain. Also check that
2810 // global property cells up to (but not including) the last object 2998 // global property cells up to (but not including) the last object
2811 // in the prototype chain are empty. 2999 // in the prototype chain are empty.
2812 CheckPrototypes(object, eax, last, ebx, edx, edi, name, &miss); 3000 CheckPrototypes(object, eax, last, ebx, edx, edi, name, &miss);
2813 3001
2814 // If the last object in the prototype chain is a global object, 3002 // If the last object in the prototype chain is a global object,
2815 // check that the global property cell is empty. 3003 // check that the global property cell is empty.
2816 if (last->IsGlobalObject()) { 3004 if (last->IsGlobalObject()) {
2817 MaybeObject* cell = GenerateCheckPropertyCell(masm(), 3005 GenerateCheckPropertyCell(
2818 GlobalObject::cast(last), 3006 masm(), Handle<GlobalObject>::cast(last), name, edx, &miss);
2819 name,
2820 edx,
2821 &miss);
2822 if (cell->IsFailure()) {
2823 miss.Unuse();
2824 return cell;
2825 }
2826 } 3007 }
2827 3008
2828 // Return undefined if maps of the full prototype chain are still the 3009 // Return undefined if maps of the full prototype chain are still the
2829 // same and no global property with this name contains a value. 3010 // same and no global property with this name contains a value.
2830 __ mov(eax, isolate()->factory()->undefined_value()); 3011 __ mov(eax, isolate()->factory()->undefined_value());
2831 __ ret(0); 3012 __ ret(0);
2832 3013
2833 __ bind(&miss); 3014 __ bind(&miss);
2834 GenerateLoadMiss(masm(), Code::LOAD_IC); 3015 GenerateLoadMiss(masm(), Code::LOAD_IC);
2835 3016
2836 // Return the generated code. 3017 // Return the generated code.
2837 return GetCode(NONEXISTENT, isolate()->heap()->empty_string()); 3018 return GetCode(NONEXISTENT, factory()->empty_string());
2838 } 3019 }
2839 3020
2840 3021
2841 MaybeObject* LoadStubCompiler::CompileLoadField(JSObject* object, 3022 Handle<Code> LoadStubCompiler::CompileLoadField(Handle<JSObject> object,
2842 JSObject* holder, 3023 Handle<JSObject> holder,
2843 int index, 3024 int index,
2844 String* name) { 3025 Handle<String> name) {
2845 // ----------- S t a t e ------------- 3026 // ----------- S t a t e -------------
2846 // -- eax : receiver 3027 // -- eax : receiver
2847 // -- ecx : name 3028 // -- ecx : name
2848 // -- esp[0] : return address 3029 // -- esp[0] : return address
2849 // ----------------------------------- 3030 // -----------------------------------
2850 Label miss; 3031 Label miss;
2851 3032
2852 GenerateLoadField(object, holder, eax, ebx, edx, edi, index, name, &miss); 3033 GenerateLoadField(object, holder, eax, ebx, edx, edi, index, name, &miss);
2853 __ bind(&miss); 3034 __ bind(&miss);
2854 GenerateLoadMiss(masm(), Code::LOAD_IC); 3035 GenerateLoadMiss(masm(), Code::LOAD_IC);
(...skipping 18 matching lines...) Expand all
2873 edi, callback, name, &miss); 3054 edi, callback, name, &miss);
2874 if (result->IsFailure()) { 3055 if (result->IsFailure()) {
2875 miss.Unuse(); 3056 miss.Unuse();
2876 return result; 3057 return result;
2877 } 3058 }
2878 3059
2879 __ bind(&miss); 3060 __ bind(&miss);
2880 GenerateLoadMiss(masm(), Code::LOAD_IC); 3061 GenerateLoadMiss(masm(), Code::LOAD_IC);
2881 3062
2882 // Return the generated code. 3063 // Return the generated code.
2883 return GetCode(CALLBACKS, name); 3064 return TryGetCode(CALLBACKS, name);
2884 } 3065 }
2885 3066
2886 3067
2887 MaybeObject* LoadStubCompiler::CompileLoadConstant(JSObject* object, 3068 Handle<Code> LoadStubCompiler::CompileLoadConstant(Handle<JSObject> object,
2888 JSObject* holder, 3069 Handle<JSObject> holder,
2889 Object* value, 3070 Handle<Object> value,
2890 String* name) { 3071 Handle<String> name) {
2891 // ----------- S t a t e ------------- 3072 // ----------- S t a t e -------------
2892 // -- eax : receiver 3073 // -- eax : receiver
2893 // -- ecx : name 3074 // -- ecx : name
2894 // -- esp[0] : return address 3075 // -- esp[0] : return address
2895 // ----------------------------------- 3076 // -----------------------------------
2896 Label miss; 3077 Label miss;
2897 3078
2898 GenerateLoadConstant(object, holder, eax, ebx, edx, edi, value, name, &miss); 3079 GenerateLoadConstant(object, holder, eax, ebx, edx, edi, value, name, &miss);
2899 __ bind(&miss); 3080 __ bind(&miss);
2900 GenerateLoadMiss(masm(), Code::LOAD_IC); 3081 GenerateLoadMiss(masm(), Code::LOAD_IC);
2901 3082
2902 // Return the generated code. 3083 // Return the generated code.
2903 return GetCode(CONSTANT_FUNCTION, name); 3084 return GetCode(CONSTANT_FUNCTION, name);
2904 } 3085 }
2905 3086
2906 3087
2907 MaybeObject* LoadStubCompiler::CompileLoadInterceptor(JSObject* receiver, 3088 MaybeObject* LoadStubCompiler::CompileLoadInterceptor(JSObject* receiver,
2908 JSObject* holder, 3089 JSObject* holder,
2909 String* name) { 3090 String* name) {
2910 // ----------- S t a t e ------------- 3091 // ----------- S t a t e -------------
2911 // -- eax : receiver 3092 // -- eax : receiver
2912 // -- ecx : name 3093 // -- ecx : name
2913 // -- esp[0] : return address 3094 // -- esp[0] : return address
2914 // ----------------------------------- 3095 // -----------------------------------
2915 Label miss; 3096 Label miss;
2916 3097
2917 LookupResult lookup; 3098 LookupResult lookup(isolate());
2918 LookupPostInterceptor(holder, name, &lookup); 3099 LookupPostInterceptor(holder, name, &lookup);
2919 3100
2920 // TODO(368): Compile in the whole chain: all the interceptors in 3101 // TODO(368): Compile in the whole chain: all the interceptors in
2921 // prototypes and ultimate answer. 3102 // prototypes and ultimate answer.
2922 GenerateLoadInterceptor(receiver, 3103 GenerateLoadInterceptor(receiver,
2923 holder, 3104 holder,
2924 &lookup, 3105 &lookup,
2925 eax, 3106 eax,
2926 ecx, 3107 ecx,
2927 edx, 3108 edx,
2928 ebx, 3109 ebx,
2929 edi, 3110 edi,
2930 name, 3111 name,
2931 &miss); 3112 &miss);
2932 3113
2933 __ bind(&miss); 3114 __ bind(&miss);
2934 GenerateLoadMiss(masm(), Code::LOAD_IC); 3115 GenerateLoadMiss(masm(), Code::LOAD_IC);
2935 3116
2936 // Return the generated code. 3117 // Return the generated code.
2937 return GetCode(INTERCEPTOR, name); 3118 return TryGetCode(INTERCEPTOR, name);
2938 } 3119 }
2939 3120
2940 3121
2941 MaybeObject* LoadStubCompiler::CompileLoadGlobal(JSObject* object, 3122 Handle<Code> LoadStubCompiler::CompileLoadGlobal(
2942 GlobalObject* holder, 3123 Handle<JSObject> object,
2943 JSGlobalPropertyCell* cell, 3124 Handle<GlobalObject> holder,
2944 String* name, 3125 Handle<JSGlobalPropertyCell> cell,
2945 bool is_dont_delete) { 3126 Handle<String> name,
3127 bool is_dont_delete) {
2946 // ----------- S t a t e ------------- 3128 // ----------- S t a t e -------------
2947 // -- eax : receiver 3129 // -- eax : receiver
2948 // -- ecx : name 3130 // -- ecx : name
2949 // -- esp[0] : return address 3131 // -- esp[0] : return address
2950 // ----------------------------------- 3132 // -----------------------------------
2951 Label miss; 3133 Label miss;
2952 3134
2953 // If the object is the holder then we know that it's a global 3135 // If the object is the holder then we know that it's a global
2954 // object which can only happen for contextual loads. In this case, 3136 // object which can only happen for contextual loads. In this case,
2955 // the receiver cannot be a smi. 3137 // the receiver cannot be a smi.
2956 if (object != holder) { 3138 if (!object.is_identical_to(holder)) {
2957 __ JumpIfSmi(eax, &miss); 3139 __ JumpIfSmi(eax, &miss);
2958 } 3140 }
2959 3141
2960 // Check that the maps haven't changed. 3142 // Check that the maps haven't changed.
2961 CheckPrototypes(object, eax, holder, ebx, edx, edi, name, &miss); 3143 CheckPrototypes(object, eax, holder, ebx, edx, edi, name, &miss);
2962 3144
2963 // Get the value from the cell. 3145 // Get the value from the cell.
2964 if (Serializer::enabled()) { 3146 if (Serializer::enabled()) {
2965 __ mov(ebx, Immediate(Handle<JSGlobalPropertyCell>(cell))); 3147 __ mov(ebx, Immediate(cell));
2966 __ mov(ebx, FieldOperand(ebx, JSGlobalPropertyCell::kValueOffset)); 3148 __ mov(ebx, FieldOperand(ebx, JSGlobalPropertyCell::kValueOffset));
2967 } else { 3149 } else {
2968 __ mov(ebx, Operand::Cell(Handle<JSGlobalPropertyCell>(cell))); 3150 __ mov(ebx, Operand::Cell(cell));
2969 } 3151 }
2970 3152
2971 // Check for deleted property if property can actually be deleted. 3153 // Check for deleted property if property can actually be deleted.
2972 if (!is_dont_delete) { 3154 if (!is_dont_delete) {
2973 __ cmp(ebx, factory()->the_hole_value()); 3155 __ cmp(ebx, factory()->the_hole_value());
2974 __ j(equal, &miss); 3156 __ j(equal, &miss);
2975 } else if (FLAG_debug_code) { 3157 } else if (FLAG_debug_code) {
2976 __ cmp(ebx, factory()->the_hole_value()); 3158 __ cmp(ebx, factory()->the_hole_value());
2977 __ Check(not_equal, "DontDelete cells can't contain the hole"); 3159 __ Check(not_equal, "DontDelete cells can't contain the hole");
2978 } 3160 }
2979 3161
2980 Counters* counters = isolate()->counters(); 3162 Counters* counters = isolate()->counters();
2981 __ IncrementCounter(counters->named_load_global_stub(), 1); 3163 __ IncrementCounter(counters->named_load_global_stub(), 1);
2982 __ mov(eax, ebx); 3164 __ mov(eax, ebx);
2983 __ ret(0); 3165 __ ret(0);
2984 3166
2985 __ bind(&miss); 3167 __ bind(&miss);
2986 __ IncrementCounter(counters->named_load_global_stub_miss(), 1); 3168 __ IncrementCounter(counters->named_load_global_stub_miss(), 1);
2987 GenerateLoadMiss(masm(), Code::LOAD_IC); 3169 GenerateLoadMiss(masm(), Code::LOAD_IC);
2988 3170
2989 // Return the generated code. 3171 // Return the generated code.
2990 return GetCode(NORMAL, name); 3172 return GetCode(NORMAL, name);
2991 } 3173 }
2992 3174
2993 3175
2994 MaybeObject* KeyedLoadStubCompiler::CompileLoadField(String* name, 3176 Handle<Code> KeyedLoadStubCompiler::CompileLoadField(Handle<String> name,
2995 JSObject* receiver, 3177 Handle<JSObject> receiver,
2996 JSObject* holder, 3178 Handle<JSObject> holder,
2997 int index) { 3179 int index) {
2998 // ----------- S t a t e ------------- 3180 // ----------- S t a t e -------------
2999 // -- eax : key 3181 // -- eax : key
3000 // -- edx : receiver 3182 // -- edx : receiver
3001 // -- esp[0] : return address 3183 // -- esp[0] : return address
3002 // ----------------------------------- 3184 // -----------------------------------
3003 Label miss; 3185 Label miss;
3004 3186
3005 Counters* counters = isolate()->counters(); 3187 Counters* counters = isolate()->counters();
3006 __ IncrementCounter(counters->keyed_load_field(), 1); 3188 __ IncrementCounter(counters->keyed_load_field(), 1);
3007 3189
3008 // Check that the name has not changed. 3190 // Check that the name has not changed.
3009 __ cmp(eax, Immediate(Handle<String>(name))); 3191 __ cmp(eax, Immediate(name));
3010 __ j(not_equal, &miss); 3192 __ j(not_equal, &miss);
3011 3193
3012 GenerateLoadField(receiver, holder, edx, ebx, ecx, edi, index, name, &miss); 3194 GenerateLoadField(receiver, holder, edx, ebx, ecx, edi, index, name, &miss);
3013 3195
3014 __ bind(&miss); 3196 __ bind(&miss);
3015 __ DecrementCounter(counters->keyed_load_field(), 1); 3197 __ DecrementCounter(counters->keyed_load_field(), 1);
3016 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); 3198 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC);
3017 3199
3018 // Return the generated code. 3200 // Return the generated code.
3019 return GetCode(FIELD, name); 3201 return GetCode(FIELD, name);
(...skipping 25 matching lines...) Expand all
3045 miss.Unuse(); 3227 miss.Unuse();
3046 return result; 3228 return result;
3047 } 3229 }
3048 3230
3049 __ bind(&miss); 3231 __ bind(&miss);
3050 3232
3051 __ DecrementCounter(counters->keyed_load_callback(), 1); 3233 __ DecrementCounter(counters->keyed_load_callback(), 1);
3052 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); 3234 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC);
3053 3235
3054 // Return the generated code. 3236 // Return the generated code.
3055 return GetCode(CALLBACKS, name); 3237 return TryGetCode(CALLBACKS, name);
3056 } 3238 }
3057 3239
3058 3240
3059 MaybeObject* KeyedLoadStubCompiler::CompileLoadConstant(String* name, 3241 Handle<Code> KeyedLoadStubCompiler::CompileLoadConstant(
3060 JSObject* receiver, 3242 Handle<String> name,
3061 JSObject* holder, 3243 Handle<JSObject> receiver,
3062 Object* value) { 3244 Handle<JSObject> holder,
3245 Handle<Object> value) {
3063 // ----------- S t a t e ------------- 3246 // ----------- S t a t e -------------
3064 // -- eax : key 3247 // -- eax : key
3065 // -- edx : receiver 3248 // -- edx : receiver
3066 // -- esp[0] : return address 3249 // -- esp[0] : return address
3067 // ----------------------------------- 3250 // -----------------------------------
3068 Label miss; 3251 Label miss;
3069 3252
3070 Counters* counters = isolate()->counters(); 3253 Counters* counters = isolate()->counters();
3071 __ IncrementCounter(counters->keyed_load_constant_function(), 1); 3254 __ IncrementCounter(counters->keyed_load_constant_function(), 1);
3072 3255
3073 // Check that the name has not changed. 3256 // Check that the name has not changed.
3074 __ cmp(eax, Immediate(Handle<String>(name))); 3257 __ cmp(eax, Immediate(name));
3075 __ j(not_equal, &miss); 3258 __ j(not_equal, &miss);
3076 3259
3077 GenerateLoadConstant(receiver, holder, edx, ebx, ecx, edi, 3260 GenerateLoadConstant(
3078 value, name, &miss); 3261 receiver, holder, edx, ebx, ecx, edi, value, name, &miss);
3079 __ bind(&miss); 3262 __ bind(&miss);
3080 __ DecrementCounter(counters->keyed_load_constant_function(), 1); 3263 __ DecrementCounter(counters->keyed_load_constant_function(), 1);
3081 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); 3264 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC);
3082 3265
3083 // Return the generated code. 3266 // Return the generated code.
3084 return GetCode(CONSTANT_FUNCTION, name); 3267 return GetCode(CONSTANT_FUNCTION, name);
3085 } 3268 }
3086 3269
3087 3270
3088 MaybeObject* KeyedLoadStubCompiler::CompileLoadInterceptor(JSObject* receiver, 3271 MaybeObject* KeyedLoadStubCompiler::CompileLoadInterceptor(JSObject* receiver,
3089 JSObject* holder, 3272 JSObject* holder,
3090 String* name) { 3273 String* name) {
3091 // ----------- S t a t e ------------- 3274 // ----------- S t a t e -------------
3092 // -- eax : key 3275 // -- eax : key
3093 // -- edx : receiver 3276 // -- edx : receiver
3094 // -- esp[0] : return address 3277 // -- esp[0] : return address
3095 // ----------------------------------- 3278 // -----------------------------------
3096 Label miss; 3279 Label miss;
3097 3280
3098 Counters* counters = isolate()->counters(); 3281 Counters* counters = isolate()->counters();
3099 __ IncrementCounter(counters->keyed_load_interceptor(), 1); 3282 __ IncrementCounter(counters->keyed_load_interceptor(), 1);
3100 3283
3101 // Check that the name has not changed. 3284 // Check that the name has not changed.
3102 __ cmp(eax, Immediate(Handle<String>(name))); 3285 __ cmp(eax, Immediate(Handle<String>(name)));
3103 __ j(not_equal, &miss); 3286 __ j(not_equal, &miss);
3104 3287
3105 LookupResult lookup; 3288 LookupResult lookup(isolate());
3106 LookupPostInterceptor(holder, name, &lookup); 3289 LookupPostInterceptor(holder, name, &lookup);
3107 GenerateLoadInterceptor(receiver, 3290 GenerateLoadInterceptor(receiver,
3108 holder, 3291 holder,
3109 &lookup, 3292 &lookup,
3110 edx, 3293 edx,
3111 eax, 3294 eax,
3112 ecx, 3295 ecx,
3113 ebx, 3296 ebx,
3114 edi, 3297 edi,
3115 name, 3298 name,
3116 &miss); 3299 &miss);
3117 __ bind(&miss); 3300 __ bind(&miss);
3118 __ DecrementCounter(counters->keyed_load_interceptor(), 1); 3301 __ DecrementCounter(counters->keyed_load_interceptor(), 1);
3119 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); 3302 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC);
3120 3303
3121 // Return the generated code. 3304 // Return the generated code.
3122 return GetCode(INTERCEPTOR, name); 3305 return TryGetCode(INTERCEPTOR, name);
3123 } 3306 }
3124 3307
3125 3308
3126 MaybeObject* KeyedLoadStubCompiler::CompileLoadArrayLength(String* name) { 3309 Handle<Code> KeyedLoadStubCompiler::CompileLoadArrayLength(
3310 Handle<String> name) {
3127 // ----------- S t a t e ------------- 3311 // ----------- S t a t e -------------
3128 // -- eax : key 3312 // -- eax : key
3129 // -- edx : receiver 3313 // -- edx : receiver
3130 // -- esp[0] : return address 3314 // -- esp[0] : return address
3131 // ----------------------------------- 3315 // -----------------------------------
3132 Label miss; 3316 Label miss;
3133 3317
3134 Counters* counters = isolate()->counters(); 3318 Counters* counters = isolate()->counters();
3135 __ IncrementCounter(counters->keyed_load_array_length(), 1); 3319 __ IncrementCounter(counters->keyed_load_array_length(), 1);
3136 3320
3137 // Check that the name has not changed. 3321 // Check that the name has not changed.
3138 __ cmp(eax, Immediate(Handle<String>(name))); 3322 __ cmp(eax, Immediate(name));
3139 __ j(not_equal, &miss); 3323 __ j(not_equal, &miss);
3140 3324
3141 GenerateLoadArrayLength(masm(), edx, ecx, &miss); 3325 GenerateLoadArrayLength(masm(), edx, ecx, &miss);
3142 __ bind(&miss); 3326 __ bind(&miss);
3143 __ DecrementCounter(counters->keyed_load_array_length(), 1); 3327 __ DecrementCounter(counters->keyed_load_array_length(), 1);
3144 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); 3328 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC);
3145 3329
3146 // Return the generated code. 3330 // Return the generated code.
3147 return GetCode(CALLBACKS, name); 3331 return GetCode(CALLBACKS, name);
3148 } 3332 }
3149 3333
3150 3334
3151 MaybeObject* KeyedLoadStubCompiler::CompileLoadStringLength(String* name) { 3335 Handle<Code> KeyedLoadStubCompiler::CompileLoadStringLength(
3336 Handle<String> name) {
3152 // ----------- S t a t e ------------- 3337 // ----------- S t a t e -------------
3153 // -- eax : key 3338 // -- eax : key
3154 // -- edx : receiver 3339 // -- edx : receiver
3155 // -- esp[0] : return address 3340 // -- esp[0] : return address
3156 // ----------------------------------- 3341 // -----------------------------------
3157 Label miss; 3342 Label miss;
3158 3343
3159 Counters* counters = isolate()->counters(); 3344 Counters* counters = isolate()->counters();
3160 __ IncrementCounter(counters->keyed_load_string_length(), 1); 3345 __ IncrementCounter(counters->keyed_load_string_length(), 1);
3161 3346
3162 // Check that the name has not changed. 3347 // Check that the name has not changed.
3163 __ cmp(eax, Immediate(Handle<String>(name))); 3348 __ cmp(eax, Immediate(name));
3164 __ j(not_equal, &miss); 3349 __ j(not_equal, &miss);
3165 3350
3166 GenerateLoadStringLength(masm(), edx, ecx, ebx, &miss, true); 3351 GenerateLoadStringLength(masm(), edx, ecx, ebx, &miss, true);
3167 __ bind(&miss); 3352 __ bind(&miss);
3168 __ DecrementCounter(counters->keyed_load_string_length(), 1); 3353 __ DecrementCounter(counters->keyed_load_string_length(), 1);
3169 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); 3354 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC);
3170 3355
3171 // Return the generated code. 3356 // Return the generated code.
3172 return GetCode(CALLBACKS, name); 3357 return GetCode(CALLBACKS, name);
3173 } 3358 }
3174 3359
3175 3360
3176 MaybeObject* KeyedLoadStubCompiler::CompileLoadFunctionPrototype(String* name) { 3361 Handle<Code> KeyedLoadStubCompiler::CompileLoadFunctionPrototype(
3362 Handle<String> name) {
3177 // ----------- S t a t e ------------- 3363 // ----------- S t a t e -------------
3178 // -- eax : key 3364 // -- eax : key
3179 // -- edx : receiver 3365 // -- edx : receiver
3180 // -- esp[0] : return address 3366 // -- esp[0] : return address
3181 // ----------------------------------- 3367 // -----------------------------------
3182 Label miss; 3368 Label miss;
3183 3369
3184 Counters* counters = isolate()->counters(); 3370 Counters* counters = isolate()->counters();
3185 __ IncrementCounter(counters->keyed_load_function_prototype(), 1); 3371 __ IncrementCounter(counters->keyed_load_function_prototype(), 1);
3186 3372
3187 // Check that the name has not changed. 3373 // Check that the name has not changed.
3188 __ cmp(eax, Immediate(Handle<String>(name))); 3374 __ cmp(eax, Immediate(name));
3189 __ j(not_equal, &miss); 3375 __ j(not_equal, &miss);
3190 3376
3191 GenerateLoadFunctionPrototype(masm(), edx, ecx, ebx, &miss); 3377 GenerateLoadFunctionPrototype(masm(), edx, ecx, ebx, &miss);
3192 __ bind(&miss); 3378 __ bind(&miss);
3193 __ DecrementCounter(counters->keyed_load_function_prototype(), 1); 3379 __ DecrementCounter(counters->keyed_load_function_prototype(), 1);
3194 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); 3380 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC);
3195 3381
3196 // Return the generated code. 3382 // Return the generated code.
3197 return GetCode(CALLBACKS, name); 3383 return GetCode(CALLBACKS, name);
3198 } 3384 }
3199 3385
3200 3386
3201 MaybeObject* KeyedLoadStubCompiler::CompileLoadElement(Map* receiver_map) { 3387 Handle<Code> KeyedLoadStubCompiler::CompileLoadElement(
3388 Handle<Map> receiver_map) {
3202 // ----------- S t a t e ------------- 3389 // ----------- S t a t e -------------
3203 // -- eax : key 3390 // -- eax : key
3204 // -- edx : receiver 3391 // -- edx : receiver
3205 // -- esp[0] : return address 3392 // -- esp[0] : return address
3206 // ----------------------------------- 3393 // -----------------------------------
3207 Code* stub; 3394
3208 ElementsKind elements_kind = receiver_map->elements_kind(); 3395 ElementsKind elements_kind = receiver_map->elements_kind();
3209 MaybeObject* maybe_stub = KeyedLoadElementStub(elements_kind).TryGetCode(); 3396 Handle<Code> stub = KeyedLoadElementStub(elements_kind).GetCode();
3210 if (!maybe_stub->To(&stub)) return maybe_stub; 3397
3211 __ DispatchMap(edx, 3398 __ DispatchMap(edx, receiver_map, stub, DO_SMI_CHECK);
3212 Handle<Map>(receiver_map),
3213 Handle<Code>(stub),
3214 DO_SMI_CHECK);
3215 3399
3216 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); 3400 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC);
3217 3401
3218 // Return the generated code. 3402 // Return the generated code.
3219 return GetCode(NORMAL, NULL); 3403 return GetCode(NORMAL, factory()->empty_string());
3220 } 3404 }
3221 3405
3222 3406
3223 MaybeObject* KeyedLoadStubCompiler::CompileLoadPolymorphic( 3407 Handle<Code> KeyedLoadStubCompiler::CompileLoadPolymorphic(
3224 MapList* receiver_maps, 3408 MapHandleList* receiver_maps,
3225 CodeList* handler_ics) { 3409 CodeHandleList* handler_ics) {
3226 // ----------- S t a t e ------------- 3410 // ----------- S t a t e -------------
3227 // -- eax : key 3411 // -- eax : key
3228 // -- edx : receiver 3412 // -- edx : receiver
3229 // -- esp[0] : return address 3413 // -- esp[0] : return address
3230 // ----------------------------------- 3414 // -----------------------------------
3231 Label miss; 3415 Label miss;
3232 __ JumpIfSmi(edx, &miss); 3416 __ JumpIfSmi(edx, &miss);
3233 3417
3234 Register map_reg = ebx; 3418 Register map_reg = ebx;
3235 __ mov(map_reg, FieldOperand(edx, HeapObject::kMapOffset)); 3419 __ mov(map_reg, FieldOperand(edx, HeapObject::kMapOffset));
3236 int receiver_count = receiver_maps->length(); 3420 int receiver_count = receiver_maps->length();
3237 for (int current = 0; current < receiver_count; ++current) { 3421 for (int current = 0; current < receiver_count; ++current) {
3238 Handle<Map> map(receiver_maps->at(current)); 3422 __ cmp(map_reg, receiver_maps->at(current));
3239 __ cmp(map_reg, map); 3423 __ j(equal, handler_ics->at(current));
3240 __ j(equal, Handle<Code>(handler_ics->at(current)));
3241 } 3424 }
3242 3425
3243 __ bind(&miss); 3426 __ bind(&miss);
3244 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); 3427 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC);
3245 3428
3246 // Return the generated code. 3429 // Return the generated code.
3247 return GetCode(NORMAL, NULL, MEGAMORPHIC); 3430 return GetCode(NORMAL, factory()->empty_string(), MEGAMORPHIC);
3248 } 3431 }
3249 3432
3250 3433
3251 // Specialized stub for constructing objects from functions which only have only 3434 // Specialized stub for constructing objects from functions which only have only
3252 // simple assignments of the form this.x = ...; in their body. 3435 // simple assignments of the form this.x = ...; in their body.
3253 MaybeObject* ConstructStubCompiler::CompileConstructStub(JSFunction* function) { 3436 MaybeObject* ConstructStubCompiler::CompileConstructStub(JSFunction* function) {
3254 // ----------- S t a t e ------------- 3437 // ----------- S t a t e -------------
3255 // -- eax : argc 3438 // -- eax : argc
3256 // -- edi : constructor 3439 // -- edi : constructor
3257 // -- esp[0] : return address 3440 // -- esp[0] : return address
(...skipping 768 matching lines...) Expand 10 before | Expand all | Expand 10 after
4026 Handle<Code> ic_miss = masm->isolate()->builtins()->KeyedStoreIC_Miss(); 4209 Handle<Code> ic_miss = masm->isolate()->builtins()->KeyedStoreIC_Miss();
4027 __ jmp(ic_miss, RelocInfo::CODE_TARGET); 4210 __ jmp(ic_miss, RelocInfo::CODE_TARGET);
4028 } 4211 }
4029 4212
4030 4213
4031 #undef __ 4214 #undef __
4032 4215
4033 } } // namespace v8::internal 4216 } } // namespace v8::internal
4034 4217
4035 #endif // V8_TARGET_ARCH_IA32 4218 #endif // V8_TARGET_ARCH_IA32
OLDNEW
« no previous file with comments | « src/ia32/regexp-macro-assembler-ia32.cc ('k') | src/ic.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698