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

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

Issue 411973002: Restructure the IC / Handler compilers (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 6 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright 2013 the V8 project authors. All rights reserved. 1 // Copyright 2013 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/v8.h" 5 #include "src/v8.h"
6 6
7 #if V8_TARGET_ARCH_ARM64 7 #if V8_TARGET_ARCH_ARM64
8 8
9 #include "src/codegen.h" 9 #include "src/codegen.h"
10 #include "src/ic-inl.h" 10 #include "src/ic-inl.h"
11 #include "src/stub-cache.h" 11 #include "src/stub-cache.h"
12 12
13 namespace v8 { 13 namespace v8 {
14 namespace internal { 14 namespace internal {
15 15
16 16
17 #define __ ACCESS_MASM(masm) 17 #define __ ACCESS_MASM(masm)
18 18
19 19
20 void StubCompiler::GenerateDictionaryNegativeLookup(MacroAssembler* masm, 20 void PropertyHandlerCompiler::GenerateDictionaryNegativeLookup(
21 Label* miss_label, 21 MacroAssembler* masm, Label* miss_label, Register receiver,
22 Register receiver, 22 Handle<Name> name, Register scratch0, Register scratch1) {
23 Handle<Name> name,
24 Register scratch0,
25 Register scratch1) {
26 ASSERT(!AreAliased(receiver, scratch0, scratch1)); 23 ASSERT(!AreAliased(receiver, scratch0, scratch1));
27 ASSERT(name->IsUniqueName()); 24 ASSERT(name->IsUniqueName());
28 Counters* counters = masm->isolate()->counters(); 25 Counters* counters = masm->isolate()->counters();
29 __ IncrementCounter(counters->negative_lookups(), 1, scratch0, scratch1); 26 __ IncrementCounter(counters->negative_lookups(), 1, scratch0, scratch1);
30 __ IncrementCounter(counters->negative_lookups_miss(), 1, scratch0, scratch1); 27 __ IncrementCounter(counters->negative_lookups_miss(), 1, scratch0, scratch1);
31 28
32 Label done; 29 Label done;
33 30
34 const int kInterceptorOrAccessCheckNeededMask = 31 const int kInterceptorOrAccessCheckNeededMask =
35 (1 << Map::kHasNamedInterceptor) | (1 << Map::kIsAccessCheckNeeded); 32 (1 << Map::kHasNamedInterceptor) | (1 << Map::kIsAccessCheckNeeded);
(...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after
194 scratch, extra, extra2, extra3); 191 scratch, extra, extra2, extra3);
195 192
196 // Cache miss: Fall-through and let caller handle the miss by 193 // Cache miss: Fall-through and let caller handle the miss by
197 // entering the runtime system. 194 // entering the runtime system.
198 __ Bind(&miss); 195 __ Bind(&miss);
199 __ IncrementCounter(counters->megamorphic_stub_cache_misses(), 1, 196 __ IncrementCounter(counters->megamorphic_stub_cache_misses(), 1,
200 extra2, extra3); 197 extra2, extra3);
201 } 198 }
202 199
203 200
204 void StubCompiler::GenerateLoadGlobalFunctionPrototype(MacroAssembler* masm, 201 void NamedLoadHandlerCompiler::GenerateDirectLoadGlobalFunctionPrototype(
205 int index, 202 MacroAssembler* masm, int index, Register prototype, Label* miss) {
206 Register prototype) {
207 // Load the global or builtins object from the current context.
208 __ Ldr(prototype, GlobalObjectMemOperand());
209 // Load the native context from the global or builtins object.
210 __ Ldr(prototype,
211 FieldMemOperand(prototype, GlobalObject::kNativeContextOffset));
212 // Load the function from the native context.
213 __ Ldr(prototype, ContextMemOperand(prototype, index));
214 // Load the initial map. The global functions all have initial maps.
215 __ Ldr(prototype,
216 FieldMemOperand(prototype, JSFunction::kPrototypeOrInitialMapOffset));
217 // Load the prototype from the initial map.
218 __ Ldr(prototype, FieldMemOperand(prototype, Map::kPrototypeOffset));
219 }
220
221
222 void StubCompiler::GenerateDirectLoadGlobalFunctionPrototype(
223 MacroAssembler* masm,
224 int index,
225 Register prototype,
226 Label* miss) {
227 Isolate* isolate = masm->isolate(); 203 Isolate* isolate = masm->isolate();
228 // Get the global function with the given index. 204 // Get the global function with the given index.
229 Handle<JSFunction> function( 205 Handle<JSFunction> function(
230 JSFunction::cast(isolate->native_context()->get(index))); 206 JSFunction::cast(isolate->native_context()->get(index)));
231 207
232 // Check we're still in the same context. 208 // Check we're still in the same context.
233 Register scratch = prototype; 209 Register scratch = prototype;
234 __ Ldr(scratch, GlobalObjectMemOperand()); 210 __ Ldr(scratch, GlobalObjectMemOperand());
235 __ Ldr(scratch, FieldMemOperand(scratch, GlobalObject::kNativeContextOffset)); 211 __ Ldr(scratch, FieldMemOperand(scratch, GlobalObject::kNativeContextOffset));
236 __ Ldr(scratch, ContextMemOperand(scratch, index)); 212 __ Ldr(scratch, ContextMemOperand(scratch, index));
237 __ Cmp(scratch, Operand(function)); 213 __ Cmp(scratch, Operand(function));
238 __ B(ne, miss); 214 __ B(ne, miss);
239 215
240 // Load its initial map. The global functions all have initial maps. 216 // Load its initial map. The global functions all have initial maps.
241 __ Mov(prototype, Operand(Handle<Map>(function->initial_map()))); 217 __ Mov(prototype, Operand(Handle<Map>(function->initial_map())));
242 // Load the prototype from the initial map. 218 // Load the prototype from the initial map.
243 __ Ldr(prototype, FieldMemOperand(prototype, Map::kPrototypeOffset)); 219 __ Ldr(prototype, FieldMemOperand(prototype, Map::kPrototypeOffset));
244 } 220 }
245 221
246 222
247 void StubCompiler::GenerateFastPropertyLoad(MacroAssembler* masm, 223 void NamedLoadHandlerCompiler::GenerateLoadFunctionPrototype(
248 Register dst, 224 MacroAssembler* masm, Register receiver, Register scratch1,
249 Register src, 225 Register scratch2, Label* miss_label) {
250 bool inobject,
251 int index,
252 Representation representation) {
253 ASSERT(!representation.IsDouble());
254 USE(representation);
255 if (inobject) {
256 int offset = index * kPointerSize;
257 __ Ldr(dst, FieldMemOperand(src, offset));
258 } else {
259 // Calculate the offset into the properties array.
260 int offset = index * kPointerSize + FixedArray::kHeaderSize;
261 __ Ldr(dst, FieldMemOperand(src, JSObject::kPropertiesOffset));
262 __ Ldr(dst, FieldMemOperand(dst, offset));
263 }
264 }
265
266
267 void StubCompiler::GenerateLoadArrayLength(MacroAssembler* masm,
268 Register receiver,
269 Register scratch,
270 Label* miss_label) {
271 ASSERT(!AreAliased(receiver, scratch));
272
273 // Check that the receiver isn't a smi.
274 __ JumpIfSmi(receiver, miss_label);
275
276 // Check that the object is a JS array.
277 __ JumpIfNotObjectType(receiver, scratch, scratch, JS_ARRAY_TYPE,
278 miss_label);
279
280 // Load length directly from the JS array.
281 __ Ldr(x0, FieldMemOperand(receiver, JSArray::kLengthOffset));
282 __ Ret();
283 }
284
285
286 void StubCompiler::GenerateLoadFunctionPrototype(MacroAssembler* masm,
287 Register receiver,
288 Register scratch1,
289 Register scratch2,
290 Label* miss_label) {
291 __ TryGetFunctionPrototype(receiver, scratch1, scratch2, miss_label); 226 __ TryGetFunctionPrototype(receiver, scratch1, scratch2, miss_label);
292 // TryGetFunctionPrototype can't put the result directly in x0 because the 227 // TryGetFunctionPrototype can't put the result directly in x0 because the
293 // 3 inputs registers can't alias and we call this function from 228 // 3 inputs registers can't alias and we call this function from
294 // LoadIC::GenerateFunctionPrototype, where receiver is x0. So we explicitly 229 // LoadIC::GenerateFunctionPrototype, where receiver is x0. So we explicitly
295 // move the result in x0. 230 // move the result in x0.
296 __ Mov(x0, scratch1); 231 __ Mov(x0, scratch1);
297 __ Ret(); 232 __ Ret();
298 } 233 }
299 234
300 235
301 // Generate code to check that a global property cell is empty. Create 236 // Generate code to check that a global property cell is empty. Create
302 // the property cell at compilation time if no cell exists for the 237 // the property cell at compilation time if no cell exists for the
303 // property. 238 // property.
304 void StubCompiler::GenerateCheckPropertyCell(MacroAssembler* masm, 239 void PropertyHandlerCompiler::GenerateCheckPropertyCell(
305 Handle<JSGlobalObject> global, 240 MacroAssembler* masm, Handle<JSGlobalObject> global, Handle<Name> name,
306 Handle<Name> name, 241 Register scratch, Label* miss) {
307 Register scratch,
308 Label* miss) {
309 Handle<Cell> cell = JSGlobalObject::EnsurePropertyCell(global, name); 242 Handle<Cell> cell = JSGlobalObject::EnsurePropertyCell(global, name);
310 ASSERT(cell->value()->IsTheHole()); 243 ASSERT(cell->value()->IsTheHole());
311 __ Mov(scratch, Operand(cell)); 244 __ Mov(scratch, Operand(cell));
312 __ Ldr(scratch, FieldMemOperand(scratch, Cell::kValueOffset)); 245 __ Ldr(scratch, FieldMemOperand(scratch, Cell::kValueOffset));
313 __ JumpIfNotRoot(scratch, Heap::kTheHoleValueRootIndex, miss); 246 __ JumpIfNotRoot(scratch, Heap::kTheHoleValueRootIndex, miss);
314 } 247 }
315 248
316 249
317 void StoreStubCompiler::GenerateNegativeHolderLookup( 250 void NamedStoreHandlerCompiler::GenerateNegativeHolderLookup(
318 MacroAssembler* masm, 251 MacroAssembler* masm, Handle<JSObject> holder, Register holder_reg,
319 Handle<JSObject> holder, 252 Handle<Name> name, Label* miss) {
320 Register holder_reg,
321 Handle<Name> name,
322 Label* miss) {
323 if (holder->IsJSGlobalObject()) { 253 if (holder->IsJSGlobalObject()) {
324 GenerateCheckPropertyCell( 254 GenerateCheckPropertyCell(
325 masm, Handle<JSGlobalObject>::cast(holder), name, scratch1(), miss); 255 masm, Handle<JSGlobalObject>::cast(holder), name, scratch1(), miss);
326 } else if (!holder->HasFastProperties() && !holder->IsJSGlobalProxy()) { 256 } else if (!holder->HasFastProperties() && !holder->IsJSGlobalProxy()) {
327 GenerateDictionaryNegativeLookup( 257 GenerateDictionaryNegativeLookup(
328 masm, miss, holder_reg, name, scratch1(), scratch2()); 258 masm, miss, holder_reg, name, scratch1(), scratch2());
329 } 259 }
330 } 260 }
331 261
332 262
333 // Generate StoreTransition code, value is passed in x0 register. 263 // Generate StoreTransition code, value is passed in x0 register.
334 // When leaving generated code after success, the receiver_reg and storage_reg 264 // When leaving generated code after success, the receiver_reg and storage_reg
335 // may be clobbered. Upon branch to miss_label, the receiver and name registers 265 // may be clobbered. Upon branch to miss_label, the receiver and name registers
336 // have their original values. 266 // have their original values.
337 void StoreStubCompiler::GenerateStoreTransition(MacroAssembler* masm, 267 void NamedStoreHandlerCompiler::GenerateStoreTransition(
338 Handle<JSObject> object, 268 MacroAssembler* masm, Handle<JSObject> object, LookupResult* lookup,
339 LookupResult* lookup, 269 Handle<Map> transition, Handle<Name> name, Register receiver_reg,
340 Handle<Map> transition, 270 Register storage_reg, Register value_reg, Register scratch1,
341 Handle<Name> name, 271 Register scratch2, Register scratch3, Label* miss_label, Label* slow) {
342 Register receiver_reg,
343 Register storage_reg,
344 Register value_reg,
345 Register scratch1,
346 Register scratch2,
347 Register scratch3,
348 Label* miss_label,
349 Label* slow) {
350 Label exit; 272 Label exit;
351 273
352 ASSERT(!AreAliased(receiver_reg, storage_reg, value_reg, 274 ASSERT(!AreAliased(receiver_reg, storage_reg, value_reg,
353 scratch1, scratch2, scratch3)); 275 scratch1, scratch2, scratch3));
354 276
355 // We don't need scratch3. 277 // We don't need scratch3.
356 scratch3 = NoReg; 278 scratch3 = NoReg;
357 279
358 int descriptor = transition->LastAdded(); 280 int descriptor = transition->LastAdded();
359 DescriptorArray* descriptors = transition->instance_descriptors(); 281 DescriptorArray* descriptors = transition->instance_descriptors();
(...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after
500 // Return the value (register x0). 422 // Return the value (register x0).
501 ASSERT(value_reg.is(x0)); 423 ASSERT(value_reg.is(x0));
502 __ Ret(); 424 __ Ret();
503 } 425 }
504 426
505 427
506 // Generate StoreField code, value is passed in x0 register. 428 // Generate StoreField code, value is passed in x0 register.
507 // When leaving generated code after success, the receiver_reg and name_reg may 429 // When leaving generated code after success, the receiver_reg and name_reg may
508 // be clobbered. Upon branch to miss_label, the receiver and name registers have 430 // be clobbered. Upon branch to miss_label, the receiver and name registers have
509 // their original values. 431 // their original values.
510 void StoreStubCompiler::GenerateStoreField(MacroAssembler* masm, 432 void NamedStoreHandlerCompiler::GenerateStoreField(
511 Handle<JSObject> object, 433 MacroAssembler* masm, Handle<JSObject> object, LookupResult* lookup,
512 LookupResult* lookup, 434 Register receiver_reg, Register name_reg, Register value_reg,
513 Register receiver_reg, 435 Register scratch1, Register scratch2, Label* miss_label) {
514 Register name_reg,
515 Register value_reg,
516 Register scratch1,
517 Register scratch2,
518 Label* miss_label) {
519 // x0 : value 436 // x0 : value
520 Label exit; 437 Label exit;
521 438
522 // Stub never generated for non-global objects that require access 439 // Stub never generated for non-global objects that require access
523 // checks. 440 // checks.
524 ASSERT(object->IsJSGlobalProxy() || !object->IsAccessCheckNeeded()); 441 ASSERT(object->IsJSGlobalProxy() || !object->IsAccessCheckNeeded());
525 442
526 FieldIndex index = lookup->GetFieldIndex(); 443 FieldIndex index = lookup->GetFieldIndex();
527 444
528 Representation representation = lookup->representation(); 445 Representation representation = lookup->representation();
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after
628 } 545 }
629 } 546 }
630 547
631 __ Bind(&exit); 548 __ Bind(&exit);
632 // Return the value (register x0). 549 // Return the value (register x0).
633 ASSERT(value_reg.is(x0)); 550 ASSERT(value_reg.is(x0));
634 __ Ret(); 551 __ Ret();
635 } 552 }
636 553
637 554
638 void StoreStubCompiler::GenerateRestoreName(MacroAssembler* masm, 555 void NamedStoreHandlerCompiler::GenerateRestoreName(MacroAssembler* masm,
639 Label* label, 556 Label* label,
640 Handle<Name> name) { 557 Handle<Name> name) {
641 if (!label->is_unused()) { 558 if (!label->is_unused()) {
642 __ Bind(label); 559 __ Bind(label);
643 __ Mov(this->name(), Operand(name)); 560 __ Mov(this->name(), Operand(name));
644 } 561 }
645 } 562 }
646 563
647 564
648 static void PushInterceptorArguments(MacroAssembler* masm, 565 static void PushInterceptorArguments(MacroAssembler* masm,
649 Register receiver, 566 Register receiver,
650 Register holder, 567 Register holder,
(...skipping 23 matching lines...) Expand all
674 IC::UtilityId id) { 591 IC::UtilityId id) {
675 PushInterceptorArguments(masm, receiver, holder, name, holder_obj); 592 PushInterceptorArguments(masm, receiver, holder, name, holder_obj);
676 593
677 __ CallExternalReference( 594 __ CallExternalReference(
678 ExternalReference(IC_Utility(id), masm->isolate()), 595 ExternalReference(IC_Utility(id), masm->isolate()),
679 StubCache::kInterceptorArgsLength); 596 StubCache::kInterceptorArgsLength);
680 } 597 }
681 598
682 599
683 // Generate call to api function. 600 // Generate call to api function.
684 void StubCompiler::GenerateFastApiCall(MacroAssembler* masm, 601 void PropertyHandlerCompiler::GenerateFastApiCall(
685 const CallOptimization& optimization, 602 MacroAssembler* masm, const CallOptimization& optimization,
686 Handle<Map> receiver_map, 603 Handle<Map> receiver_map, Register receiver, Register scratch,
687 Register receiver, 604 bool is_store, int argc, Register* values) {
688 Register scratch,
689 bool is_store,
690 int argc,
691 Register* values) {
692 ASSERT(!AreAliased(receiver, scratch)); 605 ASSERT(!AreAliased(receiver, scratch));
693 606
694 MacroAssembler::PushPopQueue queue(masm); 607 MacroAssembler::PushPopQueue queue(masm);
695 queue.Queue(receiver); 608 queue.Queue(receiver);
696 // Write the arguments to the stack frame. 609 // Write the arguments to the stack frame.
697 for (int i = 0; i < argc; i++) { 610 for (int i = 0; i < argc; i++) {
698 Register arg = values[argc-1-i]; 611 Register arg = values[argc-1-i];
699 ASSERT(!AreAliased(receiver, scratch, arg)); 612 ASSERT(!AreAliased(receiver, scratch, arg));
700 queue.Queue(arg); 613 queue.Queue(arg);
701 } 614 }
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
752 ExternalReference::DIRECT_API_CALL, 665 ExternalReference::DIRECT_API_CALL,
753 masm->isolate()); 666 masm->isolate());
754 __ Mov(api_function_address, ref); 667 __ Mov(api_function_address, ref);
755 668
756 // Jump to stub. 669 // Jump to stub.
757 CallApiFunctionStub stub(isolate, is_store, call_data_undefined, argc); 670 CallApiFunctionStub stub(isolate, is_store, call_data_undefined, argc);
758 __ TailCallStub(&stub); 671 __ TailCallStub(&stub);
759 } 672 }
760 673
761 674
762 void StubCompiler::GenerateTailCall(MacroAssembler* masm, Handle<Code> code) { 675 void PropertyAccessCompiler::GenerateTailCall(MacroAssembler* masm,
676 Handle<Code> code) {
763 __ Jump(code, RelocInfo::CODE_TARGET); 677 __ Jump(code, RelocInfo::CODE_TARGET);
764 } 678 }
765 679
766 680
767 #undef __ 681 #undef __
768 #define __ ACCESS_MASM(masm()) 682 #define __ ACCESS_MASM(masm())
769 683
770 684
771 Register StubCompiler::CheckPrototypes(Handle<HeapType> type, 685 Register PropertyHandlerCompiler::CheckPrototypes(
772 Register object_reg, 686 Handle<HeapType> type, Register object_reg, Handle<JSObject> holder,
773 Handle<JSObject> holder, 687 Register holder_reg, Register scratch1, Register scratch2,
774 Register holder_reg, 688 Handle<Name> name, Label* miss, PrototypeCheckType check) {
775 Register scratch1,
776 Register scratch2,
777 Handle<Name> name,
778 Label* miss,
779 PrototypeCheckType check) {
780 Handle<Map> receiver_map(IC::TypeToMap(*type, isolate())); 689 Handle<Map> receiver_map(IC::TypeToMap(*type, isolate()));
781 690
782 // object_reg and holder_reg registers can alias. 691 // object_reg and holder_reg registers can alias.
783 ASSERT(!AreAliased(object_reg, scratch1, scratch2)); 692 ASSERT(!AreAliased(object_reg, scratch1, scratch2));
784 ASSERT(!AreAliased(holder_reg, scratch1, scratch2)); 693 ASSERT(!AreAliased(holder_reg, scratch1, scratch2));
785 694
786 // Keep track of the current object in register reg. 695 // Keep track of the current object in register reg.
787 Register reg = object_reg; 696 Register reg = object_reg;
788 int depth = 0; 697 int depth = 0;
789 698
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
876 !current_map->is_access_check_needed()); 785 !current_map->is_access_check_needed());
877 if (current_map->IsJSGlobalProxyMap()) { 786 if (current_map->IsJSGlobalProxyMap()) {
878 __ CheckAccessGlobalProxy(reg, scratch1, scratch2, miss); 787 __ CheckAccessGlobalProxy(reg, scratch1, scratch2, miss);
879 } 788 }
880 789
881 // Return the register containing the holder. 790 // Return the register containing the holder.
882 return reg; 791 return reg;
883 } 792 }
884 793
885 794
886 void LoadStubCompiler::HandlerFrontendFooter(Handle<Name> name, Label* miss) { 795 void NamedLoadHandlerCompiler::FrontendFooter(Handle<Name> name, Label* miss) {
887 if (!miss->is_unused()) { 796 if (!miss->is_unused()) {
888 Label success; 797 Label success;
889 __ B(&success); 798 __ B(&success);
890 799
891 __ Bind(miss); 800 __ Bind(miss);
892 TailCallBuiltin(masm(), MissBuiltin(kind())); 801 TailCallBuiltin(masm(), MissBuiltin(kind()));
893 802
894 __ Bind(&success); 803 __ Bind(&success);
895 } 804 }
896 } 805 }
897 806
898 807
899 void StoreStubCompiler::HandlerFrontendFooter(Handle<Name> name, Label* miss) { 808 void NamedStoreHandlerCompiler::FrontendFooter(Handle<Name> name, Label* miss) {
900 if (!miss->is_unused()) { 809 if (!miss->is_unused()) {
901 Label success; 810 Label success;
902 __ B(&success); 811 __ B(&success);
903 812
904 GenerateRestoreName(masm(), miss, name); 813 GenerateRestoreName(masm(), miss, name);
905 TailCallBuiltin(masm(), MissBuiltin(kind())); 814 TailCallBuiltin(masm(), MissBuiltin(kind()));
906 815
907 __ Bind(&success); 816 __ Bind(&success);
908 } 817 }
909 } 818 }
910 819
911 820
912 Register LoadStubCompiler::CallbackHandlerFrontend(Handle<HeapType> type, 821 Register NamedLoadHandlerCompiler::CallbackFrontend(Handle<HeapType> type,
913 Register object_reg, 822 Register object_reg,
914 Handle<JSObject> holder, 823 Handle<JSObject> holder,
915 Handle<Name> name, 824 Handle<Name> name,
916 Handle<Object> callback) { 825 Handle<Object> callback) {
917 Label miss; 826 Label miss;
918 827
919 Register reg = HandlerFrontendHeader(type, object_reg, holder, name, &miss); 828 Register reg = FrontendHeader(type, object_reg, holder, name, &miss);
920 // HandlerFrontendHeader can return its result into scratch1() so do not 829 // FrontendHeader can return its result into scratch1() so do not
921 // use it. 830 // use it.
922 Register scratch2 = this->scratch2(); 831 Register scratch2 = this->scratch2();
923 Register scratch3 = this->scratch3(); 832 Register scratch3 = this->scratch3();
924 Register dictionary = this->scratch4(); 833 Register dictionary = this->scratch4();
925 ASSERT(!AreAliased(reg, scratch2, scratch3, dictionary)); 834 ASSERT(!AreAliased(reg, scratch2, scratch3, dictionary));
926 835
927 if (!holder->HasFastProperties() && !holder->IsJSGlobalObject()) { 836 if (!holder->HasFastProperties() && !holder->IsJSGlobalObject()) {
928 // Load the properties dictionary. 837 // Load the properties dictionary.
929 __ Ldr(dictionary, FieldMemOperand(reg, JSObject::kPropertiesOffset)); 838 __ Ldr(dictionary, FieldMemOperand(reg, JSObject::kPropertiesOffset));
930 839
(...skipping 12 matching lines...) Expand all
943 // pointer into the dictionary. Check that the value is the callback. 852 // pointer into the dictionary. Check that the value is the callback.
944 Register pointer = scratch3; 853 Register pointer = scratch3;
945 const int kElementsStartOffset = NameDictionary::kHeaderSize + 854 const int kElementsStartOffset = NameDictionary::kHeaderSize +
946 NameDictionary::kElementsStartIndex * kPointerSize; 855 NameDictionary::kElementsStartIndex * kPointerSize;
947 const int kValueOffset = kElementsStartOffset + kPointerSize; 856 const int kValueOffset = kElementsStartOffset + kPointerSize;
948 __ Ldr(scratch2, FieldMemOperand(pointer, kValueOffset)); 857 __ Ldr(scratch2, FieldMemOperand(pointer, kValueOffset));
949 __ Cmp(scratch2, Operand(callback)); 858 __ Cmp(scratch2, Operand(callback));
950 __ B(ne, &miss); 859 __ B(ne, &miss);
951 } 860 }
952 861
953 HandlerFrontendFooter(name, &miss); 862 FrontendFooter(name, &miss);
954 return reg; 863 return reg;
955 } 864 }
956 865
957 866
958 void LoadStubCompiler::GenerateLoadField(Register reg, 867 void NamedLoadHandlerCompiler::GenerateLoadField(
959 Handle<JSObject> holder, 868 Register reg, Handle<JSObject> holder, FieldIndex field,
960 FieldIndex field, 869 Representation representation) {
961 Representation representation) {
962 __ Mov(receiver(), reg); 870 __ Mov(receiver(), reg);
963 LoadFieldStub stub(isolate(), field); 871 LoadFieldStub stub(isolate(), field);
964 GenerateTailCall(masm(), stub.GetCode()); 872 GenerateTailCall(masm(), stub.GetCode());
965 } 873 }
966 874
967 875
968 void LoadStubCompiler::GenerateLoadConstant(Handle<Object> value) { 876 void NamedLoadHandlerCompiler::GenerateLoadConstant(Handle<Object> value) {
969 // Return the constant value. 877 // Return the constant value.
970 __ LoadObject(x0, value); 878 __ LoadObject(x0, value);
971 __ Ret(); 879 __ Ret();
972 } 880 }
973 881
974 882
975 void LoadStubCompiler::GenerateLoadCallback( 883 void NamedLoadHandlerCompiler::GenerateLoadCallback(
976 Register reg, 884 Register reg, Handle<ExecutableAccessorInfo> callback) {
977 Handle<ExecutableAccessorInfo> callback) {
978 ASSERT(!AreAliased(scratch2(), scratch3(), scratch4(), reg)); 885 ASSERT(!AreAliased(scratch2(), scratch3(), scratch4(), reg));
979 886
980 // Build ExecutableAccessorInfo::args_ list on the stack and push property 887 // Build ExecutableAccessorInfo::args_ list on the stack and push property
981 // name below the exit frame to make GC aware of them and store pointers to 888 // name below the exit frame to make GC aware of them and store pointers to
982 // them. 889 // them.
983 STATIC_ASSERT(PropertyCallbackArguments::kHolderIndex == 0); 890 STATIC_ASSERT(PropertyCallbackArguments::kHolderIndex == 0);
984 STATIC_ASSERT(PropertyCallbackArguments::kIsolateIndex == 1); 891 STATIC_ASSERT(PropertyCallbackArguments::kIsolateIndex == 1);
985 STATIC_ASSERT(PropertyCallbackArguments::kReturnValueDefaultValueIndex == 2); 892 STATIC_ASSERT(PropertyCallbackArguments::kReturnValueDefaultValueIndex == 2);
986 STATIC_ASSERT(PropertyCallbackArguments::kReturnValueOffset == 3); 893 STATIC_ASSERT(PropertyCallbackArguments::kReturnValueOffset == 3);
987 STATIC_ASSERT(PropertyCallbackArguments::kDataIndex == 4); 894 STATIC_ASSERT(PropertyCallbackArguments::kDataIndex == 4);
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
1020 ApiFunction fun(getter_address); 927 ApiFunction fun(getter_address);
1021 ExternalReference::Type type = ExternalReference::DIRECT_GETTER_CALL; 928 ExternalReference::Type type = ExternalReference::DIRECT_GETTER_CALL;
1022 ExternalReference ref = ExternalReference(&fun, type, isolate()); 929 ExternalReference ref = ExternalReference(&fun, type, isolate());
1023 __ Mov(getter_address_reg, ref); 930 __ Mov(getter_address_reg, ref);
1024 931
1025 CallApiGetterStub stub(isolate()); 932 CallApiGetterStub stub(isolate());
1026 __ TailCallStub(&stub); 933 __ TailCallStub(&stub);
1027 } 934 }
1028 935
1029 936
1030 void LoadStubCompiler::GenerateLoadInterceptor( 937 void NamedLoadHandlerCompiler::GenerateLoadInterceptor(
1031 Register holder_reg, 938 Register holder_reg, Handle<Object> object,
1032 Handle<Object> object, 939 Handle<JSObject> interceptor_holder, LookupResult* lookup,
1033 Handle<JSObject> interceptor_holder,
1034 LookupResult* lookup,
1035 Handle<Name> name) { 940 Handle<Name> name) {
1036 ASSERT(!AreAliased(receiver(), this->name(), 941 ASSERT(!AreAliased(receiver(), this->name(),
1037 scratch1(), scratch2(), scratch3())); 942 scratch1(), scratch2(), scratch3()));
1038 ASSERT(interceptor_holder->HasNamedInterceptor()); 943 ASSERT(interceptor_holder->HasNamedInterceptor());
1039 ASSERT(!interceptor_holder->GetNamedInterceptor()->getter()->IsUndefined()); 944 ASSERT(!interceptor_holder->GetNamedInterceptor()->getter()->IsUndefined());
1040 945
1041 // So far the most popular follow ups for interceptor loads are FIELD 946 // So far the most popular follow ups for interceptor loads are FIELD
1042 // and CALLBACKS, so inline only them, other cases may be added later. 947 // and CALLBACKS, so inline only them, other cases may be added later.
1043 bool compile_followup_inline = false; 948 bool compile_followup_inline = false;
1044 if (lookup->IsFound() && lookup->IsCacheable()) { 949 if (lookup->IsFound() && lookup->IsCacheable()) {
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
1108 masm(), receiver(), holder_reg, this->name(), interceptor_holder); 1013 masm(), receiver(), holder_reg, this->name(), interceptor_holder);
1109 1014
1110 ExternalReference ref = 1015 ExternalReference ref =
1111 ExternalReference(IC_Utility(IC::kLoadPropertyWithInterceptor), 1016 ExternalReference(IC_Utility(IC::kLoadPropertyWithInterceptor),
1112 isolate()); 1017 isolate());
1113 __ TailCallExternalReference(ref, StubCache::kInterceptorArgsLength, 1); 1018 __ TailCallExternalReference(ref, StubCache::kInterceptorArgsLength, 1);
1114 } 1019 }
1115 } 1020 }
1116 1021
1117 1022
1118 Handle<Code> StoreStubCompiler::CompileStoreCallback( 1023 Handle<Code> NamedStoreHandlerCompiler::CompileStoreCallback(
1119 Handle<JSObject> object, 1024 Handle<JSObject> object, Handle<JSObject> holder, Handle<Name> name,
1120 Handle<JSObject> holder,
1121 Handle<Name> name,
1122 Handle<ExecutableAccessorInfo> callback) { 1025 Handle<ExecutableAccessorInfo> callback) {
1123 ASM_LOCATION("StoreStubCompiler::CompileStoreCallback"); 1026 ASM_LOCATION("NamedStoreHandlerCompiler::CompileStoreCallback");
1124 Register holder_reg = HandlerFrontend( 1027 Register holder_reg =
1125 IC::CurrentTypeOf(object, isolate()), receiver(), holder, name); 1028 Frontend(IC::CurrentTypeOf(object, isolate()), receiver(), holder, name);
1126 1029
1127 // Stub never generated for non-global objects that require access checks. 1030 // Stub never generated for non-global objects that require access checks.
1128 ASSERT(holder->IsJSGlobalProxy() || !holder->IsAccessCheckNeeded()); 1031 ASSERT(holder->IsJSGlobalProxy() || !holder->IsAccessCheckNeeded());
1129 1032
1130 // receiver() and holder_reg can alias. 1033 // receiver() and holder_reg can alias.
1131 ASSERT(!AreAliased(receiver(), scratch1(), scratch2(), value())); 1034 ASSERT(!AreAliased(receiver(), scratch1(), scratch2(), value()));
1132 ASSERT(!AreAliased(holder_reg, scratch1(), scratch2(), value())); 1035 ASSERT(!AreAliased(holder_reg, scratch1(), scratch2(), value()));
1133 __ Mov(scratch1(), Operand(callback)); 1036 __ Mov(scratch1(), Operand(callback));
1134 __ Mov(scratch2(), Operand(name)); 1037 __ Mov(scratch2(), Operand(name));
1135 __ Push(receiver(), holder_reg, scratch1(), scratch2(), value()); 1038 __ Push(receiver(), holder_reg, scratch1(), scratch2(), value());
1136 1039
1137 // Do tail-call to the runtime system. 1040 // Do tail-call to the runtime system.
1138 ExternalReference store_callback_property = 1041 ExternalReference store_callback_property =
1139 ExternalReference(IC_Utility(IC::kStoreCallbackProperty), isolate()); 1042 ExternalReference(IC_Utility(IC::kStoreCallbackProperty), isolate());
1140 __ TailCallExternalReference(store_callback_property, 5, 1); 1043 __ TailCallExternalReference(store_callback_property, 5, 1);
1141 1044
1142 // Return the generated code. 1045 // Return the generated code.
1143 return GetCode(kind(), Code::FAST, name); 1046 return GetCode(kind(), Code::FAST, name);
1144 } 1047 }
1145 1048
1146 1049
1147 #undef __ 1050 #undef __
1148 #define __ ACCESS_MASM(masm) 1051 #define __ ACCESS_MASM(masm)
1149 1052
1150 1053
1151 void StoreStubCompiler::GenerateStoreViaSetter( 1054 void NamedStoreHandlerCompiler::GenerateStoreViaSetter(
1152 MacroAssembler* masm, 1055 MacroAssembler* masm, Handle<HeapType> type, Register receiver,
1153 Handle<HeapType> type,
1154 Register receiver,
1155 Handle<JSFunction> setter) { 1056 Handle<JSFunction> setter) {
1156 // ----------- S t a t e ------------- 1057 // ----------- S t a t e -------------
1157 // -- lr : return address 1058 // -- lr : return address
1158 // ----------------------------------- 1059 // -----------------------------------
1159 Label miss; 1060 Label miss;
1160 1061
1161 { 1062 {
1162 FrameScope scope(masm, StackFrame::INTERNAL); 1063 FrameScope scope(masm, StackFrame::INTERNAL);
1163 1064
1164 // Save value register, so we can restore it later. 1065 // Save value register, so we can restore it later.
(...skipping 24 matching lines...) Expand all
1189 __ Ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); 1090 __ Ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
1190 } 1091 }
1191 __ Ret(); 1092 __ Ret();
1192 } 1093 }
1193 1094
1194 1095
1195 #undef __ 1096 #undef __
1196 #define __ ACCESS_MASM(masm()) 1097 #define __ ACCESS_MASM(masm())
1197 1098
1198 1099
1199 Handle<Code> StoreStubCompiler::CompileStoreInterceptor( 1100 Handle<Code> NamedStoreHandlerCompiler::CompileStoreInterceptor(
1200 Handle<JSObject> object, 1101 Handle<JSObject> object, Handle<Name> name) {
1201 Handle<Name> name) {
1202 Label miss; 1102 Label miss;
1203 1103
1204 ASM_LOCATION("StoreStubCompiler::CompileStoreInterceptor"); 1104 ASM_LOCATION("NamedStoreHandlerCompiler::CompileStoreInterceptor");
1205 1105
1206 __ Push(receiver(), this->name(), value()); 1106 __ Push(receiver(), this->name(), value());
1207 1107
1208 // Do tail-call to the runtime system. 1108 // Do tail-call to the runtime system.
1209 ExternalReference store_ic_property = 1109 ExternalReference store_ic_property =
1210 ExternalReference(IC_Utility(IC::kStoreInterceptorProperty), isolate()); 1110 ExternalReference(IC_Utility(IC::kStoreInterceptorProperty), isolate());
1211 __ TailCallExternalReference(store_ic_property, 3, 1); 1111 __ TailCallExternalReference(store_ic_property, 3, 1);
1212 1112
1213 // Return the generated code. 1113 // Return the generated code.
1214 return GetCode(kind(), Code::FAST, name); 1114 return GetCode(kind(), Code::FAST, name);
1215 } 1115 }
1216 1116
1217 1117
1218 Handle<Code> LoadStubCompiler::CompileLoadNonexistent(Handle<HeapType> type, 1118 Handle<Code> NamedLoadHandlerCompiler::CompileLoadNonexistent(
1219 Handle<JSObject> last, 1119 Handle<HeapType> type, Handle<JSObject> last, Handle<Name> name) {
1220 Handle<Name> name) { 1120 NonexistentFrontend(type, last, name);
1221 NonexistentHandlerFrontend(type, last, name);
1222 1121
1223 // Return undefined if maps of the full prototype chain are still the 1122 // Return undefined if maps of the full prototype chain are still the
1224 // same and no global property with this name contains a value. 1123 // same and no global property with this name contains a value.
1225 __ LoadRoot(x0, Heap::kUndefinedValueRootIndex); 1124 __ LoadRoot(x0, Heap::kUndefinedValueRootIndex);
1226 __ Ret(); 1125 __ Ret();
1227 1126
1228 // Return the generated code. 1127 // Return the generated code.
1229 return GetCode(kind(), Code::FAST, name); 1128 return GetCode(kind(), Code::FAST, name);
1230 } 1129 }
1231 1130
1232 1131
1233 // TODO(all): The so-called scratch registers are significant in some cases. For 1132 // TODO(all): The so-called scratch registers are significant in some cases. For
1234 // example, KeyedStoreStubCompiler::registers()[3] (x3) is actually used for 1133 // example, PropertyAccessCompiler::keyed_store_calling_convention()[3] (x3) is
1235 // KeyedStoreCompiler::transition_map(). We should verify which registers are 1134 // actually
1236 // actually scratch registers, and which are important. For now, we use the same 1135 // used for KeyedStoreCompiler::transition_map(). We should verify which
1237 // assignments as ARM to remain on the safe side. 1136 // registers are actually scratch registers, and which are important. For now,
1137 // we use the same assignments as ARM to remain on the safe side.
1238 1138
1239 Register* LoadStubCompiler::registers() { 1139 Register* PropertyAccessCompiler::load_calling_convention() {
1240 // receiver, name, scratch1, scratch2, scratch3, scratch4. 1140 // receiver, name, scratch1, scratch2, scratch3, scratch4.
1241 Register receiver = LoadIC::ReceiverRegister(); 1141 Register receiver = LoadIC::ReceiverRegister();
1242 Register name = LoadIC::NameRegister(); 1142 Register name = LoadIC::NameRegister();
1243 static Register registers[] = { receiver, name, x3, x0, x4, x5 }; 1143 static Register registers[] = { receiver, name, x3, x0, x4, x5 };
1244 return registers; 1144 return registers;
1245 } 1145 }
1246 1146
1247 1147
1248 Register* KeyedLoadStubCompiler::registers() { 1148 Register* PropertyAccessCompiler::store_calling_convention() {
1249 // receiver, name, scratch1, scratch2, scratch3, scratch4.
1250 Register receiver = LoadIC::ReceiverRegister();
1251 Register name = LoadIC::NameRegister();
1252 static Register registers[] = { receiver, name, x3, x0, x4, x5 };
1253 return registers;
1254 }
1255
1256
1257 Register StoreStubCompiler::value() {
1258 return StoreIC::ValueRegister();
1259 }
1260
1261
1262 Register* StoreStubCompiler::registers() {
1263 // receiver, value, scratch1, scratch2, scratch3. 1149 // receiver, value, scratch1, scratch2, scratch3.
1264 Register receiver = StoreIC::ReceiverRegister(); 1150 Register receiver = StoreIC::ReceiverRegister();
1265 Register name = StoreIC::NameRegister(); 1151 Register name = StoreIC::NameRegister();
1266 static Register registers[] = { receiver, name, x3, x4, x5 }; 1152 static Register registers[] = { receiver, name, x3, x4, x5 };
1267 return registers; 1153 return registers;
1268 } 1154 }
1269 1155
1270 1156
1271 Register* KeyedStoreStubCompiler::registers() { 1157 Register* PropertyAccessCompiler::keyed_store_calling_convention() {
1272 // receiver, name, scratch1/map, scratch2, scratch3. 1158 // receiver, name, scratch1/map, scratch2, scratch3.
1273 Register receiver = KeyedStoreIC::ReceiverRegister(); 1159 Register receiver = KeyedStoreIC::ReceiverRegister();
1274 Register name = KeyedStoreIC::NameRegister(); 1160 Register name = KeyedStoreIC::NameRegister();
1275 Register map = KeyedStoreIC::MapRegister(); 1161 Register map = KeyedStoreIC::MapRegister();
1276 static Register registers[] = { receiver, name, map, x4, x5 }; 1162 static Register registers[] = { receiver, name, map, x4, x5 };
1277 return registers; 1163 return registers;
1278 } 1164 }
1279 1165
1280 1166
1167 Register NamedStoreHandlerCompiler::value() { return StoreIC::ValueRegister(); }
1168
1169
1281 #undef __ 1170 #undef __
1282 #define __ ACCESS_MASM(masm) 1171 #define __ ACCESS_MASM(masm)
1283 1172
1284 void LoadStubCompiler::GenerateLoadViaGetter(MacroAssembler* masm, 1173 void NamedLoadHandlerCompiler::GenerateLoadViaGetter(
1285 Handle<HeapType> type, 1174 MacroAssembler* masm, Handle<HeapType> type, Register receiver,
1286 Register receiver, 1175 Handle<JSFunction> getter) {
1287 Handle<JSFunction> getter) {
1288 { 1176 {
1289 FrameScope scope(masm, StackFrame::INTERNAL); 1177 FrameScope scope(masm, StackFrame::INTERNAL);
1290 1178
1291 if (!getter.is_null()) { 1179 if (!getter.is_null()) {
1292 // Call the JavaScript getter with the receiver on the stack. 1180 // Call the JavaScript getter with the receiver on the stack.
1293 if (IC::TypeToMap(*type, masm->isolate())->IsJSGlobalObjectMap()) { 1181 if (IC::TypeToMap(*type, masm->isolate())->IsJSGlobalObjectMap()) {
1294 // Swap in the global receiver. 1182 // Swap in the global receiver.
1295 __ Ldr(receiver, 1183 __ Ldr(receiver,
1296 FieldMemOperand(receiver, JSGlobalObject::kGlobalProxyOffset)); 1184 FieldMemOperand(receiver, JSGlobalObject::kGlobalProxyOffset));
1297 } 1185 }
(...skipping 12 matching lines...) Expand all
1310 __ Ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); 1198 __ Ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
1311 } 1199 }
1312 __ Ret(); 1200 __ Ret();
1313 } 1201 }
1314 1202
1315 1203
1316 #undef __ 1204 #undef __
1317 #define __ ACCESS_MASM(masm()) 1205 #define __ ACCESS_MASM(masm())
1318 1206
1319 1207
1320 Handle<Code> LoadStubCompiler::CompileLoadGlobal( 1208 Handle<Code> NamedLoadHandlerCompiler::CompileLoadGlobal(
1321 Handle<HeapType> type, 1209 Handle<HeapType> type, Handle<GlobalObject> global,
1322 Handle<GlobalObject> global, 1210 Handle<PropertyCell> cell, Handle<Name> name, bool is_dont_delete) {
1323 Handle<PropertyCell> cell,
1324 Handle<Name> name,
1325 bool is_dont_delete) {
1326 Label miss; 1211 Label miss;
1327 HandlerFrontendHeader(type, receiver(), global, name, &miss); 1212 FrontendHeader(type, receiver(), global, name, &miss);
1328 1213
1329 // Get the value from the cell. 1214 // Get the value from the cell.
1330 __ Mov(x3, Operand(cell)); 1215 __ Mov(x3, Operand(cell));
1331 __ Ldr(x4, FieldMemOperand(x3, Cell::kValueOffset)); 1216 __ Ldr(x4, FieldMemOperand(x3, Cell::kValueOffset));
1332 1217
1333 // Check for deleted property if property can actually be deleted. 1218 // Check for deleted property if property can actually be deleted.
1334 if (!is_dont_delete) { 1219 if (!is_dont_delete) {
1335 __ JumpIfRoot(x4, Heap::kTheHoleValueRootIndex, &miss); 1220 __ JumpIfRoot(x4, Heap::kTheHoleValueRootIndex, &miss);
1336 } 1221 }
1337 1222
1338 Counters* counters = isolate()->counters(); 1223 Counters* counters = isolate()->counters();
1339 __ IncrementCounter(counters->named_load_global_stub(), 1, x1, x3); 1224 __ IncrementCounter(counters->named_load_global_stub(), 1, x1, x3);
1340 __ Mov(x0, x4); 1225 __ Mov(x0, x4);
1341 __ Ret(); 1226 __ Ret();
1342 1227
1343 HandlerFrontendFooter(name, &miss); 1228 FrontendFooter(name, &miss);
1344 1229
1345 // Return the generated code. 1230 // Return the generated code.
1346 return GetCode(kind(), Code::NORMAL, name); 1231 return GetCode(kind(), Code::NORMAL, name);
1347 } 1232 }
1348 1233
1349 1234
1350 Handle<Code> BaseLoadStoreStubCompiler::CompilePolymorphicIC( 1235 Handle<Code> PropertyICCompiler::CompilePolymorphic(TypeHandleList* types,
1351 TypeHandleList* types, 1236 CodeHandleList* handlers,
1352 CodeHandleList* handlers, 1237 Handle<Name> name,
1353 Handle<Name> name, 1238 Code::StubType type,
1354 Code::StubType type, 1239 IcCheckType check) {
1355 IcCheckType check) {
1356 Label miss; 1240 Label miss;
1357 1241
1358 if (check == PROPERTY && 1242 if (check == PROPERTY &&
1359 (kind() == Code::KEYED_LOAD_IC || kind() == Code::KEYED_STORE_IC)) { 1243 (kind() == Code::KEYED_LOAD_IC || kind() == Code::KEYED_STORE_IC)) {
1360 __ CompareAndBranch(this->name(), Operand(name), ne, &miss); 1244 __ CompareAndBranch(this->name(), Operand(name), ne, &miss);
1361 } 1245 }
1362 1246
1363 Label number_case; 1247 Label number_case;
1364 Label* smi_target = IncludesNumberType(types) ? &number_case : &miss; 1248 Label* smi_target = IncludesNumberType(types) ? &number_case : &miss;
1365 __ JumpIfSmi(receiver(), smi_target); 1249 __ JumpIfSmi(receiver(), smi_target);
(...skipping 22 matching lines...) Expand all
1388 } 1272 }
1389 } 1273 }
1390 ASSERT(number_of_handled_maps != 0); 1274 ASSERT(number_of_handled_maps != 0);
1391 1275
1392 __ Bind(&miss); 1276 __ Bind(&miss);
1393 TailCallBuiltin(masm(), MissBuiltin(kind())); 1277 TailCallBuiltin(masm(), MissBuiltin(kind()));
1394 1278
1395 // Return the generated code. 1279 // Return the generated code.
1396 InlineCacheState state = 1280 InlineCacheState state =
1397 (number_of_handled_maps > 1) ? POLYMORPHIC : MONOMORPHIC; 1281 (number_of_handled_maps > 1) ? POLYMORPHIC : MONOMORPHIC;
1398 return GetICCode(kind(), type, name, state); 1282 return GetCode(kind(), type, name, state);
1399 } 1283 }
1400 1284
1401 1285
1402 void StoreStubCompiler::GenerateStoreArrayLength() { 1286 void NamedStoreHandlerCompiler::GenerateStoreArrayLength() {
1403 // Prepare tail call to StoreIC_ArrayLength. 1287 // Prepare tail call to StoreIC_ArrayLength.
1404 __ Push(receiver(), value()); 1288 __ Push(receiver(), value());
1405 1289
1406 ExternalReference ref = 1290 ExternalReference ref =
1407 ExternalReference(IC_Utility(IC::kStoreIC_ArrayLength), 1291 ExternalReference(IC_Utility(IC::kStoreIC_ArrayLength),
1408 masm()->isolate()); 1292 masm()->isolate());
1409 __ TailCallExternalReference(ref, 2, 1); 1293 __ TailCallExternalReference(ref, 2, 1);
1410 } 1294 }
1411 1295
1412 1296
1413 Handle<Code> KeyedStoreStubCompiler::CompileStorePolymorphic( 1297 Handle<Code> PropertyICCompiler::CompileIndexedStorePolymorphic(
1414 MapHandleList* receiver_maps, 1298 MapHandleList* receiver_maps, CodeHandleList* handler_stubs,
1415 CodeHandleList* handler_stubs,
1416 MapHandleList* transitioned_maps) { 1299 MapHandleList* transitioned_maps) {
1417 Label miss; 1300 Label miss;
1418 1301
1419 ASM_LOCATION("KeyedStoreStubCompiler::CompileStorePolymorphic"); 1302 ASM_LOCATION("PropertyICCompiler::CompileStorePolymorphic");
1420 1303
1421 __ JumpIfSmi(receiver(), &miss); 1304 __ JumpIfSmi(receiver(), &miss);
1422 1305
1423 int receiver_count = receiver_maps->length(); 1306 int receiver_count = receiver_maps->length();
1424 __ Ldr(scratch1(), FieldMemOperand(receiver(), HeapObject::kMapOffset)); 1307 __ Ldr(scratch1(), FieldMemOperand(receiver(), HeapObject::kMapOffset));
1425 for (int i = 0; i < receiver_count; i++) { 1308 for (int i = 0; i < receiver_count; i++) {
1426 __ Cmp(scratch1(), Operand(receiver_maps->at(i))); 1309 __ Cmp(scratch1(), Operand(receiver_maps->at(i)));
1427 1310
1428 Label skip; 1311 Label skip;
1429 __ B(&skip, ne); 1312 __ B(&skip, ne);
1430 if (!transitioned_maps->at(i).is_null()) { 1313 if (!transitioned_maps->at(i).is_null()) {
1431 // This argument is used by the handler stub. For example, see 1314 // This argument is used by the handler stub. For example, see
1432 // ElementsTransitionGenerator::GenerateMapChangeElementsTransition. 1315 // ElementsTransitionGenerator::GenerateMapChangeElementsTransition.
1433 __ Mov(transition_map(), Operand(transitioned_maps->at(i))); 1316 __ Mov(transition_map(), Operand(transitioned_maps->at(i)));
1434 } 1317 }
1435 __ Jump(handler_stubs->at(i), RelocInfo::CODE_TARGET); 1318 __ Jump(handler_stubs->at(i), RelocInfo::CODE_TARGET);
1436 __ Bind(&skip); 1319 __ Bind(&skip);
1437 } 1320 }
1438 1321
1439 __ Bind(&miss); 1322 __ Bind(&miss);
1440 TailCallBuiltin(masm(), MissBuiltin(kind())); 1323 TailCallBuiltin(masm(), MissBuiltin(kind()));
1441 1324
1442 return GetICCode( 1325 return GetCode(kind(), Code::NORMAL, factory()->empty_string(), POLYMORPHIC);
1443 kind(), Code::NORMAL, factory()->empty_string(), POLYMORPHIC);
1444 } 1326 }
1445 1327
1446 1328
1447 #undef __ 1329 #undef __
1448 #define __ ACCESS_MASM(masm) 1330 #define __ ACCESS_MASM(masm)
1449 1331
1450 void KeyedLoadStubCompiler::GenerateLoadDictionaryElement( 1332 void IndexedHandlerCompiler::GenerateLoadDictionaryElement(
1451 MacroAssembler* masm) { 1333 MacroAssembler* masm) {
1452 // The return address is in lr. 1334 // The return address is in lr.
1453 Label slow, miss; 1335 Label slow, miss;
1454 1336
1455 Register result = x0; 1337 Register result = x0;
1456 Register key = LoadIC::NameRegister(); 1338 Register key = LoadIC::NameRegister();
1457 Register receiver = LoadIC::ReceiverRegister(); 1339 Register receiver = LoadIC::ReceiverRegister();
1458 ASSERT(receiver.is(x1)); 1340 ASSERT(receiver.is(x1));
1459 ASSERT(key.is(x2)); 1341 ASSERT(key.is(x2));
1460 1342
1461 __ JumpIfNotSmi(key, &miss); 1343 __ JumpIfNotSmi(key, &miss);
1462 __ Ldr(x4, FieldMemOperand(receiver, JSObject::kElementsOffset)); 1344 __ Ldr(x4, FieldMemOperand(receiver, JSObject::kElementsOffset));
1463 __ LoadFromNumberDictionary(&slow, x4, key, result, x7, x3, x5, x6); 1345 __ LoadFromNumberDictionary(&slow, x4, key, result, x7, x3, x5, x6);
1464 __ Ret(); 1346 __ Ret();
1465 1347
1466 __ Bind(&slow); 1348 __ Bind(&slow);
1467 __ IncrementCounter( 1349 __ IncrementCounter(
1468 masm->isolate()->counters()->keyed_load_external_array_slow(), 1, x4, x3); 1350 masm->isolate()->counters()->keyed_load_external_array_slow(), 1, x4, x3);
1469 TailCallBuiltin(masm, Builtins::kKeyedLoadIC_Slow); 1351 TailCallBuiltin(masm, Builtins::kKeyedLoadIC_Slow);
1470 1352
1471 // Miss case, call the runtime. 1353 // Miss case, call the runtime.
1472 __ Bind(&miss); 1354 __ Bind(&miss);
1473 TailCallBuiltin(masm, Builtins::kKeyedLoadIC_Miss); 1355 TailCallBuiltin(masm, Builtins::kKeyedLoadIC_Miss);
1474 } 1356 }
1475 1357
1476 1358
1477 } } // namespace v8::internal 1359 } } // namespace v8::internal
1478 1360
1479 #endif // V8_TARGET_ARCH_ARM64 1361 #endif // V8_TARGET_ARCH_ARM64
OLDNEW
« no previous file with comments | « src/arm64/code-stubs-arm64.cc ('k') | src/builtins.cc » ('j') | src/ia32/stub-cache-ia32.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698