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

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

Issue 12330012: ES6 symbols: Allow symbols as property names (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Platform ports Created 7 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/arm/code-stubs-arm.cc ('k') | src/arm/macro-assembler-arm.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 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
57 __ b(eq, global_object); 57 __ b(eq, global_object);
58 __ cmp(type, Operand(JS_BUILTINS_OBJECT_TYPE)); 58 __ cmp(type, Operand(JS_BUILTINS_OBJECT_TYPE));
59 __ b(eq, global_object); 59 __ b(eq, global_object);
60 __ cmp(type, Operand(JS_GLOBAL_PROXY_TYPE)); 60 __ cmp(type, Operand(JS_GLOBAL_PROXY_TYPE));
61 __ b(eq, global_object); 61 __ b(eq, global_object);
62 } 62 }
63 63
64 64
65 // Generated code falls through if the receiver is a regular non-global 65 // Generated code falls through if the receiver is a regular non-global
66 // JS object with slow properties and no interceptors. 66 // JS object with slow properties and no interceptors.
67 static void GenerateStringDictionaryReceiverCheck(MacroAssembler* masm, 67 static void GenerateNameDictionaryReceiverCheck(MacroAssembler* masm,
68 Register receiver, 68 Register receiver,
69 Register elements, 69 Register elements,
70 Register t0, 70 Register t0,
71 Register t1, 71 Register t1,
72 Label* miss) { 72 Label* miss) {
73 // Register usage: 73 // Register usage:
74 // receiver: holds the receiver on entry and is unchanged. 74 // receiver: holds the receiver on entry and is unchanged.
75 // elements: holds the property dictionary on fall through. 75 // elements: holds the property dictionary on fall through.
76 // Scratch registers: 76 // Scratch registers:
77 // t0: used to holds the receiver map. 77 // t0: used to holds the receiver map.
78 // t1: used to holds the receiver instance type, receiver bit mask and 78 // t1: used to holds the receiver instance type, receiver bit mask and
79 // elements map. 79 // elements map.
80 80
81 // Check that the receiver isn't a smi. 81 // Check that the receiver isn't a smi.
82 __ JumpIfSmi(receiver, miss); 82 __ JumpIfSmi(receiver, miss);
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
124 Register result, 124 Register result,
125 Register scratch1, 125 Register scratch1,
126 Register scratch2) { 126 Register scratch2) {
127 // Main use of the scratch registers. 127 // Main use of the scratch registers.
128 // scratch1: Used as temporary and to hold the capacity of the property 128 // scratch1: Used as temporary and to hold the capacity of the property
129 // dictionary. 129 // dictionary.
130 // scratch2: Used as temporary. 130 // scratch2: Used as temporary.
131 Label done; 131 Label done;
132 132
133 // Probe the dictionary. 133 // Probe the dictionary.
134 StringDictionaryLookupStub::GeneratePositiveLookup(masm, 134 NameDictionaryLookupStub::GeneratePositiveLookup(masm,
135 miss, 135 miss,
136 &done, 136 &done,
137 elements, 137 elements,
138 name, 138 name,
139 scratch1, 139 scratch1,
140 scratch2); 140 scratch2);
141 141
142 // If probing finds an entry check that the value is a normal 142 // If probing finds an entry check that the value is a normal
143 // property. 143 // property.
144 __ bind(&done); // scratch2 == elements + 4 * index 144 __ bind(&done); // scratch2 == elements + 4 * index
145 const int kElementsStartOffset = StringDictionary::kHeaderSize + 145 const int kElementsStartOffset = NameDictionary::kHeaderSize +
146 StringDictionary::kElementsStartIndex * kPointerSize; 146 NameDictionary::kElementsStartIndex * kPointerSize;
147 const int kDetailsOffset = kElementsStartOffset + 2 * kPointerSize; 147 const int kDetailsOffset = kElementsStartOffset + 2 * kPointerSize;
148 __ ldr(scratch1, FieldMemOperand(scratch2, kDetailsOffset)); 148 __ ldr(scratch1, FieldMemOperand(scratch2, kDetailsOffset));
149 __ tst(scratch1, Operand(PropertyDetails::TypeField::kMask << kSmiTagSize)); 149 __ tst(scratch1, Operand(PropertyDetails::TypeField::kMask << kSmiTagSize));
150 __ b(ne, miss); 150 __ b(ne, miss);
151 151
152 // Get the value at the masked, scaled index and return. 152 // Get the value at the masked, scaled index and return.
153 __ ldr(result, 153 __ ldr(result,
154 FieldMemOperand(scratch2, kElementsStartOffset + 1 * kPointerSize)); 154 FieldMemOperand(scratch2, kElementsStartOffset + 1 * kPointerSize));
155 } 155 }
156 156
(...skipping 16 matching lines...) Expand all
173 Register value, 173 Register value,
174 Register scratch1, 174 Register scratch1,
175 Register scratch2) { 175 Register scratch2) {
176 // Main use of the scratch registers. 176 // Main use of the scratch registers.
177 // scratch1: Used as temporary and to hold the capacity of the property 177 // scratch1: Used as temporary and to hold the capacity of the property
178 // dictionary. 178 // dictionary.
179 // scratch2: Used as temporary. 179 // scratch2: Used as temporary.
180 Label done; 180 Label done;
181 181
182 // Probe the dictionary. 182 // Probe the dictionary.
183 StringDictionaryLookupStub::GeneratePositiveLookup(masm, 183 NameDictionaryLookupStub::GeneratePositiveLookup(masm,
184 miss, 184 miss,
185 &done, 185 &done,
186 elements, 186 elements,
187 name, 187 name,
188 scratch1, 188 scratch1,
189 scratch2); 189 scratch2);
190 190
191 // If probing finds an entry in the dictionary check that the value 191 // If probing finds an entry in the dictionary check that the value
192 // is a normal property that is not read only. 192 // is a normal property that is not read only.
193 __ bind(&done); // scratch2 == elements + 4 * index 193 __ bind(&done); // scratch2 == elements + 4 * index
194 const int kElementsStartOffset = StringDictionary::kHeaderSize + 194 const int kElementsStartOffset = NameDictionary::kHeaderSize +
195 StringDictionary::kElementsStartIndex * kPointerSize; 195 NameDictionary::kElementsStartIndex * kPointerSize;
196 const int kDetailsOffset = kElementsStartOffset + 2 * kPointerSize; 196 const int kDetailsOffset = kElementsStartOffset + 2 * kPointerSize;
197 const int kTypeAndReadOnlyMask = 197 const int kTypeAndReadOnlyMask =
198 (PropertyDetails::TypeField::kMask | 198 (PropertyDetails::TypeField::kMask |
199 PropertyDetails::AttributesField::encode(READ_ONLY)) << kSmiTagSize; 199 PropertyDetails::AttributesField::encode(READ_ONLY)) << kSmiTagSize;
200 __ ldr(scratch1, FieldMemOperand(scratch2, kDetailsOffset)); 200 __ ldr(scratch1, FieldMemOperand(scratch2, kDetailsOffset));
201 __ tst(scratch1, Operand(kTypeAndReadOnlyMask)); 201 __ tst(scratch1, Operand(kTypeAndReadOnlyMask));
202 __ b(ne, miss); 202 __ b(ne, miss);
203 203
204 // Store the value at the masked, scaled index and return. 204 // Store the value at the masked, scaled index and return.
205 const int kValueOffset = kElementsStartOffset + kPointerSize; 205 const int kValueOffset = kElementsStartOffset + kPointerSize;
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
296 MemOperand(scratch1, key, LSL, kPointerSizeLog2 - kSmiTagSize)); 296 MemOperand(scratch1, key, LSL, kPointerSizeLog2 - kSmiTagSize));
297 __ LoadRoot(ip, Heap::kTheHoleValueRootIndex); 297 __ LoadRoot(ip, Heap::kTheHoleValueRootIndex);
298 __ cmp(scratch2, ip); 298 __ cmp(scratch2, ip);
299 // In case the loaded value is the_hole we have to consult GetProperty 299 // In case the loaded value is the_hole we have to consult GetProperty
300 // to ensure the prototype chain is searched. 300 // to ensure the prototype chain is searched.
301 __ b(eq, out_of_range); 301 __ b(eq, out_of_range);
302 __ mov(result, scratch2); 302 __ mov(result, scratch2);
303 } 303 }
304 304
305 305
306 // Checks whether a key is an array index string or an internalized string. 306 // Checks whether a key is an array index string or a unique name.
307 // Falls through if a key is an internalized string. 307 // Falls through if a key is a unique name.
308 static void GenerateKeyStringCheck(MacroAssembler* masm, 308 static void GenerateKeyNameCheck(MacroAssembler* masm,
309 Register key, 309 Register key,
310 Register map, 310 Register map,
311 Register hash, 311 Register hash,
312 Label* index_string, 312 Label* index_string,
313 Label* not_internalized) { 313 Label* not_unique) {
314 // The key is not a smi. 314 // The key is not a smi.
315 // Is it a string? 315 Label unique;
316 __ CompareObjectType(key, map, hash, FIRST_NONSTRING_TYPE); 316 // Is it a name?
317 __ b(ge, not_internalized); 317 __ CompareObjectType(key, map, hash, LAST_UNIQUE_NAME_TYPE);
318 __ b(hi, not_unique);
319 STATIC_ASSERT(LAST_UNIQUE_NAME_TYPE == FIRST_NONSTRING_TYPE);
320 __ b(eq, &unique);
318 321
319 // Is the string an array index, with cached numeric value? 322 // Is the string an array index, with cached numeric value?
320 __ ldr(hash, FieldMemOperand(key, String::kHashFieldOffset)); 323 __ ldr(hash, FieldMemOperand(key, Name::kHashFieldOffset));
321 __ tst(hash, Operand(String::kContainsCachedArrayIndexMask)); 324 __ tst(hash, Operand(Name::kContainsCachedArrayIndexMask));
322 __ b(eq, index_string); 325 __ b(eq, index_string);
323 326
324 // Is the string internalized? 327 // Is the string internalized?
325 // map: key map 328 // map: key map
326 __ ldrb(hash, FieldMemOperand(map, Map::kInstanceTypeOffset)); 329 __ ldrb(hash, FieldMemOperand(map, Map::kInstanceTypeOffset));
327 STATIC_ASSERT(kInternalizedTag != 0); 330 STATIC_ASSERT(kInternalizedTag != 0);
328 __ tst(hash, Operand(kIsInternalizedMask)); 331 __ tst(hash, Operand(kIsInternalizedMask));
329 __ b(eq, not_internalized); 332 __ b(eq, not_unique);
333
334 __ bind(&unique);
330 } 335 }
331 336
332 337
333 // Defined in ic.cc. 338 // Defined in ic.cc.
334 Object* CallIC_Miss(Arguments args); 339 Object* CallIC_Miss(Arguments args);
335 340
336 // The generated code does not accept smi keys. 341 // The generated code does not accept smi keys.
337 // The generated code falls through if both probes miss. 342 // The generated code falls through if both probes miss.
338 void CallICBase::GenerateMonomorphicCacheProbe(MacroAssembler* masm, 343 void CallICBase::GenerateMonomorphicCacheProbe(MacroAssembler* masm,
339 int argc, 344 int argc,
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
420 void CallICBase::GenerateNormal(MacroAssembler* masm, int argc) { 425 void CallICBase::GenerateNormal(MacroAssembler* masm, int argc) {
421 // ----------- S t a t e ------------- 426 // ----------- S t a t e -------------
422 // -- r2 : name 427 // -- r2 : name
423 // -- lr : return address 428 // -- lr : return address
424 // ----------------------------------- 429 // -----------------------------------
425 Label miss; 430 Label miss;
426 431
427 // Get the receiver of the function from the stack into r1. 432 // Get the receiver of the function from the stack into r1.
428 __ ldr(r1, MemOperand(sp, argc * kPointerSize)); 433 __ ldr(r1, MemOperand(sp, argc * kPointerSize));
429 434
430 GenerateStringDictionaryReceiverCheck(masm, r1, r0, r3, r4, &miss); 435 GenerateNameDictionaryReceiverCheck(masm, r1, r0, r3, r4, &miss);
431 436
432 // r0: elements 437 // r0: elements
433 // Search the dictionary - put result in register r1. 438 // Search the dictionary - put result in register r1.
434 GenerateDictionaryLoad(masm, &miss, r0, r2, r1, r3, r4); 439 GenerateDictionaryLoad(masm, &miss, r0, r2, r1, r3, r4);
435 440
436 GenerateFunctionTailCall(masm, argc, &miss, r4); 441 GenerateFunctionTailCall(masm, argc, &miss, r4);
437 442
438 __ bind(&miss); 443 __ bind(&miss);
439 } 444 }
440 445
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
524 void KeyedCallIC::GenerateMegamorphic(MacroAssembler* masm, int argc) { 529 void KeyedCallIC::GenerateMegamorphic(MacroAssembler* masm, int argc) {
525 // ----------- S t a t e ------------- 530 // ----------- S t a t e -------------
526 // -- r2 : name 531 // -- r2 : name
527 // -- lr : return address 532 // -- lr : return address
528 // ----------------------------------- 533 // -----------------------------------
529 534
530 // Get the receiver of the function from the stack into r1. 535 // Get the receiver of the function from the stack into r1.
531 __ ldr(r1, MemOperand(sp, argc * kPointerSize)); 536 __ ldr(r1, MemOperand(sp, argc * kPointerSize));
532 537
533 Label do_call, slow_call, slow_load, slow_reload_receiver; 538 Label do_call, slow_call, slow_load, slow_reload_receiver;
534 Label check_number_dictionary, check_string, lookup_monomorphic_cache; 539 Label check_number_dictionary, check_name, lookup_monomorphic_cache;
535 Label index_smi, index_string; 540 Label index_smi, index_name;
536 541
537 // Check that the key is a smi. 542 // Check that the key is a smi.
538 __ JumpIfNotSmi(r2, &check_string); 543 __ JumpIfNotSmi(r2, &check_name);
539 __ bind(&index_smi); 544 __ bind(&index_smi);
540 // Now the key is known to be a smi. This place is also jumped to from below 545 // Now the key is known to be a smi. This place is also jumped to from below
541 // where a numeric string is converted to a smi. 546 // where a numeric string is converted to a smi.
542 547
543 GenerateKeyedLoadReceiverCheck( 548 GenerateKeyedLoadReceiverCheck(
544 masm, r1, r0, r3, Map::kHasIndexedInterceptor, &slow_call); 549 masm, r1, r0, r3, Map::kHasIndexedInterceptor, &slow_call);
545 550
546 GenerateFastArrayLoad( 551 GenerateFastArrayLoad(
547 masm, r1, r2, r4, r3, r0, r1, &check_number_dictionary, &slow_load); 552 masm, r1, r2, r4, r3, r0, r1, &check_number_dictionary, &slow_load);
548 Counters* counters = masm->isolate()->counters(); 553 Counters* counters = masm->isolate()->counters();
(...skipping 26 matching lines...) Expand all
575 { 580 {
576 FrameScope scope(masm, StackFrame::INTERNAL); 581 FrameScope scope(masm, StackFrame::INTERNAL);
577 __ push(r2); // save the key 582 __ push(r2); // save the key
578 __ Push(r1, r2); // pass the receiver and the key 583 __ Push(r1, r2); // pass the receiver and the key
579 __ CallRuntime(Runtime::kKeyedGetProperty, 2); 584 __ CallRuntime(Runtime::kKeyedGetProperty, 2);
580 __ pop(r2); // restore the key 585 __ pop(r2); // restore the key
581 } 586 }
582 __ mov(r1, r0); 587 __ mov(r1, r0);
583 __ jmp(&do_call); 588 __ jmp(&do_call);
584 589
585 __ bind(&check_string); 590 __ bind(&check_name);
586 GenerateKeyStringCheck(masm, r2, r0, r3, &index_string, &slow_call); 591 GenerateKeyNameCheck(masm, r2, r0, r3, &index_name, &slow_call);
587 592
588 // The key is known to be internalized. 593 // The key is known to be a uniquq name.
589 // If the receiver is a regular JS object with slow properties then do 594 // If the receiver is a regular JS object with slow properties then do
590 // a quick inline probe of the receiver's dictionary. 595 // a quick inline probe of the receiver's dictionary.
591 // Otherwise do the monomorphic cache probe. 596 // Otherwise do the monomorphic cache probe.
592 GenerateKeyedLoadReceiverCheck( 597 GenerateKeyedLoadReceiverCheck(
593 masm, r1, r0, r3, Map::kHasNamedInterceptor, &lookup_monomorphic_cache); 598 masm, r1, r0, r3, Map::kHasNamedInterceptor, &lookup_monomorphic_cache);
594 599
595 __ ldr(r0, FieldMemOperand(r1, JSObject::kPropertiesOffset)); 600 __ ldr(r0, FieldMemOperand(r1, JSObject::kPropertiesOffset));
596 __ ldr(r3, FieldMemOperand(r0, HeapObject::kMapOffset)); 601 __ ldr(r3, FieldMemOperand(r0, HeapObject::kMapOffset));
597 __ LoadRoot(ip, Heap::kHashTableMapRootIndex); 602 __ LoadRoot(ip, Heap::kHashTableMapRootIndex);
598 __ cmp(r3, ip); 603 __ cmp(r3, ip);
599 __ b(ne, &lookup_monomorphic_cache); 604 __ b(ne, &lookup_monomorphic_cache);
600 605
601 GenerateDictionaryLoad(masm, &slow_load, r0, r2, r1, r3, r4); 606 GenerateDictionaryLoad(masm, &slow_load, r0, r2, r1, r3, r4);
602 __ IncrementCounter(counters->keyed_call_generic_lookup_dict(), 1, r0, r3); 607 __ IncrementCounter(counters->keyed_call_generic_lookup_dict(), 1, r0, r3);
603 __ jmp(&do_call); 608 __ jmp(&do_call);
604 609
605 __ bind(&lookup_monomorphic_cache); 610 __ bind(&lookup_monomorphic_cache);
606 __ IncrementCounter(counters->keyed_call_generic_lookup_cache(), 1, r0, r3); 611 __ IncrementCounter(counters->keyed_call_generic_lookup_cache(), 1, r0, r3);
607 GenerateMonomorphicCacheProbe(masm, 612 GenerateMonomorphicCacheProbe(masm,
608 argc, 613 argc,
609 Code::KEYED_CALL_IC, 614 Code::KEYED_CALL_IC,
610 Code::kNoExtraICState); 615 Code::kNoExtraICState);
611 // Fall through on miss. 616 // Fall through on miss.
612 617
613 __ bind(&slow_call); 618 __ bind(&slow_call);
614 // This branch is taken if: 619 // This branch is taken if:
615 // - the receiver requires boxing or access check, 620 // - the receiver requires boxing or access check,
616 // - the key is neither smi nor an internalized string, 621 // - the key is neither smi nor a unique name,
617 // - the value loaded is not a function, 622 // - the value loaded is not a function,
618 // - there is hope that the runtime will create a monomorphic call stub 623 // - there is hope that the runtime will create a monomorphic call stub
619 // that will get fetched next time. 624 // that will get fetched next time.
620 __ IncrementCounter(counters->keyed_call_generic_slow(), 1, r0, r3); 625 __ IncrementCounter(counters->keyed_call_generic_slow(), 1, r0, r3);
621 GenerateMiss(masm, argc); 626 GenerateMiss(masm, argc);
622 627
623 __ bind(&index_string); 628 __ bind(&index_name);
624 __ IndexFromHash(r3, r2); 629 __ IndexFromHash(r3, r2);
625 // Now jump to the place where smi keys are handled. 630 // Now jump to the place where smi keys are handled.
626 __ jmp(&index_smi); 631 __ jmp(&index_smi);
627 } 632 }
628 633
629 634
630 void KeyedCallIC::GenerateNormal(MacroAssembler* masm, int argc) { 635 void KeyedCallIC::GenerateNormal(MacroAssembler* masm, int argc) {
631 // ----------- S t a t e ------------- 636 // ----------- S t a t e -------------
632 // -- r2 : name 637 // -- r2 : name
633 // -- lr : return address 638 // -- lr : return address
634 // ----------------------------------- 639 // -----------------------------------
635 640
636 // Check if the name is a string. 641 // Check if the name is really a name.
637 Label miss; 642 Label miss;
638 __ JumpIfSmi(r2, &miss); 643 __ JumpIfSmi(r2, &miss);
639 __ IsObjectJSStringType(r2, r0, &miss); 644 __ IsObjectNameType(r2, r0, &miss);
640 645
641 CallICBase::GenerateNormal(masm, argc); 646 CallICBase::GenerateNormal(masm, argc);
642 __ bind(&miss); 647 __ bind(&miss);
643 GenerateMiss(masm, argc); 648 GenerateMiss(masm, argc);
644 } 649 }
645 650
646 651
647 // Defined in ic.cc. 652 // Defined in ic.cc.
648 Object* LoadIC_Miss(Arguments args); 653 Object* LoadIC_Miss(Arguments args);
649 654
(...skipping 18 matching lines...) Expand all
668 673
669 void LoadIC::GenerateNormal(MacroAssembler* masm) { 674 void LoadIC::GenerateNormal(MacroAssembler* masm) {
670 // ----------- S t a t e ------------- 675 // ----------- S t a t e -------------
671 // -- r2 : name 676 // -- r2 : name
672 // -- lr : return address 677 // -- lr : return address
673 // -- r0 : receiver 678 // -- r0 : receiver
674 // -- sp[0] : receiver 679 // -- sp[0] : receiver
675 // ----------------------------------- 680 // -----------------------------------
676 Label miss; 681 Label miss;
677 682
678 GenerateStringDictionaryReceiverCheck(masm, r0, r1, r3, r4, &miss); 683 GenerateNameDictionaryReceiverCheck(masm, r0, r1, r3, r4, &miss);
679 684
680 // r1: elements 685 // r1: elements
681 GenerateDictionaryLoad(masm, &miss, r1, r2, r0, r3, r4); 686 GenerateDictionaryLoad(masm, &miss, r1, r2, r0, r3, r4);
682 __ Ret(); 687 __ Ret();
683 688
684 // Cache miss: Jump to runtime. 689 // Cache miss: Jump to runtime.
685 __ bind(&miss); 690 __ bind(&miss);
686 GenerateMiss(masm); 691 GenerateMiss(masm);
687 } 692 }
688 693
(...skipping 222 matching lines...) Expand 10 before | Expand all | Expand 10 after
911 __ TailCallRuntime(Runtime::kKeyedGetProperty, 2, 1); 916 __ TailCallRuntime(Runtime::kKeyedGetProperty, 2, 1);
912 } 917 }
913 918
914 919
915 void KeyedLoadIC::GenerateGeneric(MacroAssembler* masm) { 920 void KeyedLoadIC::GenerateGeneric(MacroAssembler* masm) {
916 // ---------- S t a t e -------------- 921 // ---------- S t a t e --------------
917 // -- lr : return address 922 // -- lr : return address
918 // -- r0 : key 923 // -- r0 : key
919 // -- r1 : receiver 924 // -- r1 : receiver
920 // ----------------------------------- 925 // -----------------------------------
921 Label slow, check_string, index_smi, index_string, property_array_property; 926 Label slow, check_name, index_smi, index_name, property_array_property;
922 Label probe_dictionary, check_number_dictionary; 927 Label probe_dictionary, check_number_dictionary;
923 928
924 Register key = r0; 929 Register key = r0;
925 Register receiver = r1; 930 Register receiver = r1;
926 931
927 Isolate* isolate = masm->isolate(); 932 Isolate* isolate = masm->isolate();
928 933
929 // Check that the key is a smi. 934 // Check that the key is a smi.
930 __ JumpIfNotSmi(key, &check_string); 935 __ JumpIfNotSmi(key, &check_name);
931 __ bind(&index_smi); 936 __ bind(&index_smi);
932 // Now the key is known to be a smi. This place is also jumped to from below 937 // Now the key is known to be a smi. This place is also jumped to from below
933 // where a numeric string is converted to a smi. 938 // where a numeric string is converted to a smi.
934 939
935 GenerateKeyedLoadReceiverCheck( 940 GenerateKeyedLoadReceiverCheck(
936 masm, receiver, r2, r3, Map::kHasIndexedInterceptor, &slow); 941 masm, receiver, r2, r3, Map::kHasIndexedInterceptor, &slow);
937 942
938 // Check the receiver's map to see if it has fast elements. 943 // Check the receiver's map to see if it has fast elements.
939 __ CheckFastElements(r2, r3, &check_number_dictionary); 944 __ CheckFastElements(r2, r3, &check_number_dictionary);
940 945
(...skipping 16 matching lines...) Expand all
957 __ mov(r2, Operand(r0, ASR, kSmiTagSize)); 962 __ mov(r2, Operand(r0, ASR, kSmiTagSize));
958 __ LoadFromNumberDictionary(&slow, r4, r0, r0, r2, r3, r5); 963 __ LoadFromNumberDictionary(&slow, r4, r0, r0, r2, r3, r5);
959 __ Ret(); 964 __ Ret();
960 965
961 // Slow case, key and receiver still in r0 and r1. 966 // Slow case, key and receiver still in r0 and r1.
962 __ bind(&slow); 967 __ bind(&slow);
963 __ IncrementCounter(isolate->counters()->keyed_load_generic_slow(), 968 __ IncrementCounter(isolate->counters()->keyed_load_generic_slow(),
964 1, r2, r3); 969 1, r2, r3);
965 GenerateRuntimeGetProperty(masm); 970 GenerateRuntimeGetProperty(masm);
966 971
967 __ bind(&check_string); 972 __ bind(&check_name);
968 GenerateKeyStringCheck(masm, key, r2, r3, &index_string, &slow); 973 GenerateKeyNameCheck(masm, key, r2, r3, &index_name, &slow);
969 974
970 GenerateKeyedLoadReceiverCheck( 975 GenerateKeyedLoadReceiverCheck(
971 masm, receiver, r2, r3, Map::kHasNamedInterceptor, &slow); 976 masm, receiver, r2, r3, Map::kHasNamedInterceptor, &slow);
972 977
973 // If the receiver is a fast-case object, check the keyed lookup 978 // If the receiver is a fast-case object, check the keyed lookup
974 // cache. Otherwise probe the dictionary. 979 // cache. Otherwise probe the dictionary.
975 __ ldr(r3, FieldMemOperand(r1, JSObject::kPropertiesOffset)); 980 __ ldr(r3, FieldMemOperand(r1, JSObject::kPropertiesOffset));
976 __ ldr(r4, FieldMemOperand(r3, HeapObject::kMapOffset)); 981 __ ldr(r4, FieldMemOperand(r3, HeapObject::kMapOffset));
977 __ LoadRoot(ip, Heap::kHashTableMapRootIndex); 982 __ LoadRoot(ip, Heap::kHashTableMapRootIndex);
978 __ cmp(r4, ip); 983 __ cmp(r4, ip);
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
1069 // r3: elements 1074 // r3: elements
1070 __ ldr(r2, FieldMemOperand(r1, HeapObject::kMapOffset)); 1075 __ ldr(r2, FieldMemOperand(r1, HeapObject::kMapOffset));
1071 __ ldrb(r2, FieldMemOperand(r2, Map::kInstanceTypeOffset)); 1076 __ ldrb(r2, FieldMemOperand(r2, Map::kInstanceTypeOffset));
1072 GenerateGlobalInstanceTypeCheck(masm, r2, &slow); 1077 GenerateGlobalInstanceTypeCheck(masm, r2, &slow);
1073 // Load the property to r0. 1078 // Load the property to r0.
1074 GenerateDictionaryLoad(masm, &slow, r3, r0, r0, r2, r4); 1079 GenerateDictionaryLoad(masm, &slow, r3, r0, r0, r2, r4);
1075 __ IncrementCounter( 1080 __ IncrementCounter(
1076 isolate->counters()->keyed_load_generic_symbol(), 1, r2, r3); 1081 isolate->counters()->keyed_load_generic_symbol(), 1, r2, r3);
1077 __ Ret(); 1082 __ Ret();
1078 1083
1079 __ bind(&index_string); 1084 __ bind(&index_name);
1080 __ IndexFromHash(r3, key); 1085 __ IndexFromHash(r3, key);
1081 // Now jump to the place where smi keys are handled. 1086 // Now jump to the place where smi keys are handled.
1082 __ jmp(&index_smi); 1087 __ jmp(&index_smi);
1083 } 1088 }
1084 1089
1085 1090
1086 void KeyedLoadIC::GenerateString(MacroAssembler* masm) { 1091 void KeyedLoadIC::GenerateString(MacroAssembler* masm) {
1087 // ---------- S t a t e -------------- 1092 // ---------- S t a t e --------------
1088 // -- lr : return address 1093 // -- lr : return address
1089 // -- r0 : key (index) 1094 // -- r0 : key (index)
(...skipping 450 matching lines...) Expand 10 before | Expand all | Expand 10 after
1540 1545
1541 void StoreIC::GenerateNormal(MacroAssembler* masm) { 1546 void StoreIC::GenerateNormal(MacroAssembler* masm) {
1542 // ----------- S t a t e ------------- 1547 // ----------- S t a t e -------------
1543 // -- r0 : value 1548 // -- r0 : value
1544 // -- r1 : receiver 1549 // -- r1 : receiver
1545 // -- r2 : name 1550 // -- r2 : name
1546 // -- lr : return address 1551 // -- lr : return address
1547 // ----------------------------------- 1552 // -----------------------------------
1548 Label miss; 1553 Label miss;
1549 1554
1550 GenerateStringDictionaryReceiverCheck(masm, r1, r3, r4, r5, &miss); 1555 GenerateNameDictionaryReceiverCheck(masm, r1, r3, r4, r5, &miss);
1551 1556
1552 GenerateDictionaryStore(masm, &miss, r3, r2, r0, r4, r5); 1557 GenerateDictionaryStore(masm, &miss, r3, r2, r0, r4, r5);
1553 Counters* counters = masm->isolate()->counters(); 1558 Counters* counters = masm->isolate()->counters();
1554 __ IncrementCounter(counters->store_normal_hit(), 1559 __ IncrementCounter(counters->store_normal_hit(),
1555 1, r4, r5); 1560 1, r4, r5);
1556 __ Ret(); 1561 __ Ret();
1557 1562
1558 __ bind(&miss); 1563 __ bind(&miss);
1559 __ IncrementCounter(counters->store_normal_miss(), 1, r4, r5); 1564 __ IncrementCounter(counters->store_normal_miss(), 1, r4, r5);
1560 GenerateMiss(masm); 1565 GenerateMiss(masm);
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after
1676 } else { 1681 } else {
1677 ASSERT(Assembler::GetCondition(branch_instr) == ne); 1682 ASSERT(Assembler::GetCondition(branch_instr) == ne);
1678 patcher.EmitCondition(eq); 1683 patcher.EmitCondition(eq);
1679 } 1684 }
1680 } 1685 }
1681 1686
1682 1687
1683 } } // namespace v8::internal 1688 } } // namespace v8::internal
1684 1689
1685 #endif // V8_TARGET_ARCH_ARM 1690 #endif // V8_TARGET_ARCH_ARM
OLDNEW
« no previous file with comments | « src/arm/code-stubs-arm.cc ('k') | src/arm/macro-assembler-arm.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698