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

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

Issue 7348008: Merge up to 8597 to experimental/gc from the bleeding edge. (Closed) Base URL: http://v8.googlecode.com/svn/branches/experimental/gc/
Patch Set: '' Created 9 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
« no previous file with comments | « src/mips/full-codegen-mips.cc ('k') | src/mips/macro-assembler-mips.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 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
73 // Scratch registers: 73 // Scratch registers:
74 // scratch0: used to holds the receiver map. 74 // scratch0: used to holds the receiver map.
75 // scratch1: used to holds the receiver instance type, receiver bit mask 75 // scratch1: used to holds the receiver instance type, receiver bit mask
76 // and elements map. 76 // and elements map.
77 77
78 // Check that the receiver isn't a smi. 78 // Check that the receiver isn't a smi.
79 __ JumpIfSmi(receiver, miss); 79 __ JumpIfSmi(receiver, miss);
80 80
81 // Check that the receiver is a valid JS object. 81 // Check that the receiver is a valid JS object.
82 __ GetObjectType(receiver, scratch0, scratch1); 82 __ GetObjectType(receiver, scratch0, scratch1);
83 __ Branch(miss, lt, scratch1, Operand(FIRST_JS_OBJECT_TYPE)); 83 __ Branch(miss, lt, scratch1, Operand(FIRST_SPEC_OBJECT_TYPE));
84 84
85 // If this assert fails, we have to check upper bound too. 85 // If this assert fails, we have to check upper bound too.
86 ASSERT(LAST_TYPE == JS_FUNCTION_TYPE); 86 STATIC_ASSERT(LAST_TYPE == LAST_SPEC_OBJECT_TYPE);
87 87
88 GenerateGlobalInstanceTypeCheck(masm, scratch1, miss); 88 GenerateGlobalInstanceTypeCheck(masm, scratch1, miss);
89 89
90 // Check that the global object does not require access checks. 90 // Check that the global object does not require access checks.
91 __ lbu(scratch1, FieldMemOperand(scratch0, Map::kBitFieldOffset)); 91 __ lbu(scratch1, FieldMemOperand(scratch0, Map::kBitFieldOffset));
92 __ And(scratch1, scratch1, Operand((1 << Map::kIsAccessCheckNeeded) | 92 __ And(scratch1, scratch1, Operand((1 << Map::kIsAccessCheckNeeded) |
93 (1 << Map::kHasNamedInterceptor))); 93 (1 << Map::kHasNamedInterceptor)));
94 __ Branch(miss, ne, scratch1, Operand(zero_reg)); 94 __ Branch(miss, ne, scratch1, Operand(zero_reg));
95 95
96 __ lw(elements, FieldMemOperand(receiver, JSObject::kPropertiesOffset)); 96 __ lw(elements, FieldMemOperand(receiver, JSObject::kPropertiesOffset));
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after
207 const int kValueOffset = kElementsStartOffset + kPointerSize; 207 const int kValueOffset = kElementsStartOffset + kPointerSize;
208 __ Addu(scratch2, scratch2, Operand(kValueOffset - kHeapObjectTag)); 208 __ Addu(scratch2, scratch2, Operand(kValueOffset - kHeapObjectTag));
209 __ sw(value, MemOperand(scratch2)); 209 __ sw(value, MemOperand(scratch2));
210 210
211 // Update the write barrier. Make sure not to clobber the value. 211 // Update the write barrier. Make sure not to clobber the value.
212 __ mov(scratch1, value); 212 __ mov(scratch1, value);
213 __ RecordWrite(elements, scratch2, scratch1); 213 __ RecordWrite(elements, scratch2, scratch1);
214 } 214 }
215 215
216 216
217 static void GenerateNumberDictionaryLoad(MacroAssembler* masm,
218 Label* miss,
219 Register elements,
220 Register key,
221 Register result,
222 Register reg0,
223 Register reg1,
224 Register reg2) {
225 // Register use:
226 //
227 // elements - holds the slow-case elements of the receiver on entry.
228 // Unchanged unless 'result' is the same register.
229 //
230 // key - holds the smi key on entry.
231 // Unchanged unless 'result' is the same register.
232 //
233 //
234 // result - holds the result on exit if the load succeeded.
235 // Allowed to be the same as 'key' or 'result'.
236 // Unchanged on bailout so 'key' or 'result' can be used
237 // in further computation.
238 //
239 // Scratch registers:
240 //
241 // reg0 - holds the untagged key on entry and holds the hash once computed.
242 //
243 // reg1 - Used to hold the capacity mask of the dictionary.
244 //
245 // reg2 - Used for the index into the dictionary.
246 // at - Temporary (avoid MacroAssembler instructions also using 'at').
247 Label done;
248
249 // Compute the hash code from the untagged key. This must be kept in sync
250 // with ComputeIntegerHash in utils.h.
251 //
252 // hash = ~hash + (hash << 15);
253 __ nor(reg1, reg0, zero_reg);
254 __ sll(at, reg0, 15);
255 __ addu(reg0, reg1, at);
256
257 // hash = hash ^ (hash >> 12);
258 __ srl(at, reg0, 12);
259 __ xor_(reg0, reg0, at);
260
261 // hash = hash + (hash << 2);
262 __ sll(at, reg0, 2);
263 __ addu(reg0, reg0, at);
264
265 // hash = hash ^ (hash >> 4);
266 __ srl(at, reg0, 4);
267 __ xor_(reg0, reg0, at);
268
269 // hash = hash * 2057;
270 __ li(reg1, Operand(2057));
271 __ mul(reg0, reg0, reg1);
272
273 // hash = hash ^ (hash >> 16);
274 __ srl(at, reg0, 16);
275 __ xor_(reg0, reg0, at);
276
277 // Compute the capacity mask.
278 __ lw(reg1, FieldMemOperand(elements, NumberDictionary::kCapacityOffset));
279 __ sra(reg1, reg1, kSmiTagSize);
280 __ Subu(reg1, reg1, Operand(1));
281
282 // Generate an unrolled loop that performs a few probes before giving up.
283 static const int kProbes = 4;
284 for (int i = 0; i < kProbes; i++) {
285 // Use reg2 for index calculations and keep the hash intact in reg0.
286 __ mov(reg2, reg0);
287 // Compute the masked index: (hash + i + i * i) & mask.
288 if (i > 0) {
289 __ Addu(reg2, reg2, Operand(NumberDictionary::GetProbeOffset(i)));
290 }
291 __ and_(reg2, reg2, reg1);
292
293 // Scale the index by multiplying by the element size.
294 ASSERT(NumberDictionary::kEntrySize == 3);
295 __ sll(at, reg2, 1); // 2x.
296 __ addu(reg2, reg2, at); // reg2 = reg2 * 3.
297
298 // Check if the key is identical to the name.
299 __ sll(at, reg2, kPointerSizeLog2);
300 __ addu(reg2, elements, at);
301
302 __ lw(at, FieldMemOperand(reg2, NumberDictionary::kElementsStartOffset));
303 if (i != kProbes - 1) {
304 __ Branch(&done, eq, key, Operand(at));
305 } else {
306 __ Branch(miss, ne, key, Operand(at));
307 }
308 }
309
310 __ bind(&done);
311 // Check that the value is a normal property.
312 // reg2: elements + (index * kPointerSize).
313 const int kDetailsOffset =
314 NumberDictionary::kElementsStartOffset + 2 * kPointerSize;
315 __ lw(reg1, FieldMemOperand(reg2, kDetailsOffset));
316 __ And(at, reg1, Operand(Smi::FromInt(PropertyDetails::TypeField::mask())));
317 __ Branch(miss, ne, at, Operand(zero_reg));
318
319 // Get the value at the masked, scaled index and return.
320 const int kValueOffset =
321 NumberDictionary::kElementsStartOffset + kPointerSize;
322 __ lw(result, FieldMemOperand(reg2, kValueOffset));
323 }
324
325
326 void LoadIC::GenerateArrayLength(MacroAssembler* masm) { 217 void LoadIC::GenerateArrayLength(MacroAssembler* masm) {
327 // ----------- S t a t e ------------- 218 // ----------- S t a t e -------------
328 // -- a2 : name 219 // -- a2 : name
329 // -- ra : return address 220 // -- ra : return address
330 // -- a0 : receiver 221 // -- a0 : receiver
331 // -- sp[0] : receiver 222 // -- sp[0] : receiver
332 // ----------------------------------- 223 // -----------------------------------
333 Label miss; 224 Label miss;
334 225
335 StubCompiler::GenerateLoadArrayLength(masm, a0, a3, &miss); 226 StubCompiler::GenerateLoadArrayLength(masm, a0, a3, &miss);
(...skipping 224 matching lines...) Expand 10 before | Expand all | Expand 10 after
560 451
561 // Check that the value isn't a smi. 452 // Check that the value isn't a smi.
562 __ JumpIfSmi(a1, miss); 453 __ JumpIfSmi(a1, miss);
563 454
564 // Check that the value is a JSFunction. 455 // Check that the value is a JSFunction.
565 __ GetObjectType(a1, scratch, scratch); 456 __ GetObjectType(a1, scratch, scratch);
566 __ Branch(miss, ne, scratch, Operand(JS_FUNCTION_TYPE)); 457 __ Branch(miss, ne, scratch, Operand(JS_FUNCTION_TYPE));
567 458
568 // Invoke the function. 459 // Invoke the function.
569 ParameterCount actual(argc); 460 ParameterCount actual(argc);
570 __ InvokeFunction(a1, actual, JUMP_FUNCTION); 461 __ InvokeFunction(a1, actual, JUMP_FUNCTION,
462 NullCallWrapper(), CALL_AS_METHOD);
571 } 463 }
572 464
573 465
574 static void GenerateCallNormal(MacroAssembler* masm, int argc) { 466 static void GenerateCallNormal(MacroAssembler* masm, int argc) {
575 // ----------- S t a t e ------------- 467 // ----------- S t a t e -------------
576 // -- a2 : name 468 // -- a2 : name
577 // -- ra : return address 469 // -- ra : return address
578 // ----------------------------------- 470 // -----------------------------------
579 Label miss; 471 Label miss;
580 472
(...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after
743 635
744 __ bind(&check_number_dictionary); 636 __ bind(&check_number_dictionary);
745 // a2: key 637 // a2: key
746 // a3: elements map 638 // a3: elements map
747 // t0: elements pointer 639 // t0: elements pointer
748 // Check whether the elements is a number dictionary. 640 // Check whether the elements is a number dictionary.
749 __ LoadRoot(at, Heap::kHashTableMapRootIndex); 641 __ LoadRoot(at, Heap::kHashTableMapRootIndex);
750 __ Branch(&slow_load, ne, a3, Operand(at)); 642 __ Branch(&slow_load, ne, a3, Operand(at));
751 __ sra(a0, a2, kSmiTagSize); 643 __ sra(a0, a2, kSmiTagSize);
752 // a0: untagged index 644 // a0: untagged index
753 GenerateNumberDictionaryLoad(masm, &slow_load, t0, a2, a1, a0, a3, t1); 645 __ LoadFromNumberDictionary(&slow_load, t0, a2, a1, a0, a3, t1);
754 __ IncrementCounter(counters->keyed_call_generic_smi_dict(), 1, a0, a3); 646 __ IncrementCounter(counters->keyed_call_generic_smi_dict(), 1, a0, a3);
755 __ jmp(&do_call); 647 __ jmp(&do_call);
756 648
757 __ bind(&slow_load); 649 __ bind(&slow_load);
758 // This branch is taken when calling KeyedCallIC_Miss is neither required 650 // This branch is taken when calling KeyedCallIC_Miss is neither required
759 // nor beneficial. 651 // nor beneficial.
760 __ IncrementCounter(counters->keyed_call_generic_slow_load(), 1, a0, a3); 652 __ IncrementCounter(counters->keyed_call_generic_slow_load(), 1, a0, a3);
761 __ EnterInternalFrame(); 653 __ EnterInternalFrame();
762 __ push(a2); // Save the key. 654 __ push(a2); // Save the key.
763 __ Push(a1, a2); // Pass the receiver and the key. 655 __ Push(a1, a2); // Pass the receiver and the key.
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after
885 777
886 __ mov(a3, a0); 778 __ mov(a3, a0);
887 __ Push(a3, a2); 779 __ Push(a3, a2);
888 780
889 // Perform tail call to the entry. 781 // Perform tail call to the entry.
890 ExternalReference ref = ExternalReference(IC_Utility(kLoadIC_Miss), isolate); 782 ExternalReference ref = ExternalReference(IC_Utility(kLoadIC_Miss), isolate);
891 __ TailCallExternalReference(ref, 2, 1); 783 __ TailCallExternalReference(ref, 2, 1);
892 } 784 }
893 785
894 786
787 static MemOperand GenerateMappedArgumentsLookup(MacroAssembler* masm,
788 Register object,
789 Register key,
790 Register scratch1,
791 Register scratch2,
792 Register scratch3,
793 Label* unmapped_case,
794 Label* slow_case) {
795 Heap* heap = masm->isolate()->heap();
796
797 // Check that the receiver is a JSObject. Because of the map check
798 // later, we do not need to check for interceptors or whether it
799 // requires access checks.
800 __ JumpIfSmi(object, slow_case);
801 // Check that the object is some kind of JSObject.
802 __ GetObjectType(object, scratch1, scratch2);
803 __ Branch(slow_case, lt, scratch2, Operand(FIRST_JS_RECEIVER_TYPE));
804
805 // Check that the key is a positive smi.
806 __ And(scratch1, key, Operand(0x8000001));
807 __ Branch(slow_case, ne, scratch1, Operand(zero_reg));
808
809 // Load the elements into scratch1 and check its map.
810 Handle<Map> arguments_map(heap->non_strict_arguments_elements_map());
811 __ lw(scratch1, FieldMemOperand(object, JSObject::kElementsOffset));
812 __ CheckMap(scratch1, scratch2, arguments_map, slow_case, DONT_DO_SMI_CHECK);
813
814 // Check if element is in the range of mapped arguments. If not, jump
815 // to the unmapped lookup with the parameter map in scratch1.
816 __ lw(scratch2, FieldMemOperand(scratch1, FixedArray::kLengthOffset));
817 __ Subu(scratch2, scratch2, Operand(Smi::FromInt(2)));
818 __ Branch(unmapped_case, Ugreater_equal, key, Operand(scratch2));
819
820 // Load element index and check whether it is the hole.
821 const int kOffset =
822 FixedArray::kHeaderSize + 2 * kPointerSize - kHeapObjectTag;
823
824 __ li(scratch3, Operand(kPointerSize >> 1));
825 __ mul(scratch3, key, scratch3);
826 __ Addu(scratch3, scratch3, Operand(kOffset));
827
828 __ Addu(scratch2, scratch1, scratch3);
829 __ lw(scratch2, MemOperand(scratch2));
830 __ LoadRoot(scratch3, Heap::kTheHoleValueRootIndex);
831 __ Branch(unmapped_case, eq, scratch2, Operand(scratch3));
832
833 // Load value from context and return it. We can reuse scratch1 because
834 // we do not jump to the unmapped lookup (which requires the parameter
835 // map in scratch1).
836 __ lw(scratch1, FieldMemOperand(scratch1, FixedArray::kHeaderSize));
837 __ li(scratch3, Operand(kPointerSize >> 1));
838 __ mul(scratch3, scratch2, scratch3);
839 __ Addu(scratch3, scratch3, Operand(Context::kHeaderSize - kHeapObjectTag));
840 __ Addu(scratch2, scratch1, scratch3);
841 return MemOperand(scratch2);
842 }
843
844
845 static MemOperand GenerateUnmappedArgumentsLookup(MacroAssembler* masm,
846 Register key,
847 Register parameter_map,
848 Register scratch,
849 Label* slow_case) {
850 // Element is in arguments backing store, which is referenced by the
851 // second element of the parameter_map. The parameter_map register
852 // must be loaded with the parameter map of the arguments object and is
853 // overwritten.
854 const int kBackingStoreOffset = FixedArray::kHeaderSize + kPointerSize;
855 Register backing_store = parameter_map;
856 __ lw(backing_store, FieldMemOperand(parameter_map, kBackingStoreOffset));
857 Handle<Map> fixed_array_map(masm->isolate()->heap()->fixed_array_map());
858 __ CheckMap(backing_store, scratch, fixed_array_map, slow_case,
859 DONT_DO_SMI_CHECK);
860 __ lw(scratch, FieldMemOperand(backing_store, FixedArray::kLengthOffset));
861 __ Branch(slow_case, Ugreater_equal, key, Operand(scratch));
862 __ li(scratch, Operand(kPointerSize >> 1));
863 __ mul(scratch, key, scratch);
864 __ Addu(scratch,
865 scratch,
866 Operand(FixedArray::kHeaderSize - kHeapObjectTag));
867 __ Addu(scratch, backing_store, scratch);
868 return MemOperand(scratch);
869 }
870
871
872 void KeyedLoadIC::GenerateNonStrictArguments(MacroAssembler* masm) {
873 // ---------- S t a t e --------------
874 // -- lr : return address
875 // -- a0 : key
876 // -- a1 : receiver
877 // -----------------------------------
878 Label slow, notin;
879 MemOperand mapped_location =
880 GenerateMappedArgumentsLookup(masm, a1, a0, a2, a3, t0, &notin, &slow);
881 __ lw(v0, mapped_location);
882 __ Ret();
883 __ bind(&notin);
884 // The unmapped lookup expects that the parameter map is in a2.
885 MemOperand unmapped_location =
886 GenerateUnmappedArgumentsLookup(masm, a0, a2, a3, &slow);
887 __ lw(a2, unmapped_location);
888 __ Branch(&slow, eq, a2, Operand(a3));
889 __ LoadRoot(a3, Heap::kTheHoleValueRootIndex);
890 __ mov(v0, a2);
891 __ Ret();
892 __ bind(&slow);
893 GenerateMiss(masm, false);
894 }
895
896
897 void KeyedStoreIC::GenerateNonStrictArguments(MacroAssembler* masm) {
898 // ---------- S t a t e --------------
899 // -- a0 : value
900 // -- a1 : key
901 // -- a2 : receiver
902 // -- lr : return address
903 // -----------------------------------
904 Label slow, notin;
905 MemOperand mapped_location =
906 GenerateMappedArgumentsLookup(masm, a2, a1, a3, t0, t1, &notin, &slow);
907 __ sw(a0, mapped_location);
908 // Verify mapped_location MemOperand is register, with no offset.
909 ASSERT_EQ(mapped_location.offset(), 0);
910 __ RecordWrite(a3, mapped_location.rm(), t5);
911 __ Ret(USE_DELAY_SLOT);
912 __ mov(v0, a0); // (In delay slot) return the value stored in v0.
913 __ bind(&notin);
914 // The unmapped lookup expects that the parameter map is in a3.
915 MemOperand unmapped_location =
916 GenerateUnmappedArgumentsLookup(masm, a1, a3, t0, &slow);
917 __ sw(a0, unmapped_location);
918 ASSERT_EQ(unmapped_location.offset(), 0);
919 __ RecordWrite(a3, unmapped_location.rm(), t5);
920 __ Ret(USE_DELAY_SLOT);
921 __ mov(v0, a0); // (In delay slot) return the value stored in v0.
922 __ bind(&slow);
923 GenerateMiss(masm, false);
924 }
925
926
927 void KeyedCallIC::GenerateNonStrictArguments(MacroAssembler* masm,
928 int argc) {
929 // ----------- S t a t e -------------
930 // -- a2 : name
931 // -- lr : return address
932 // -----------------------------------
933 Label slow, notin;
934 // Load receiver.
935 __ lw(a1, MemOperand(sp, argc * kPointerSize));
936 MemOperand mapped_location =
937 GenerateMappedArgumentsLookup(masm, a1, a2, a3, t0, t1, &notin, &slow);
938 __ lw(a1, mapped_location);
939 GenerateFunctionTailCall(masm, argc, &slow, a3);
940 __ bind(&notin);
941 // The unmapped lookup expects that the parameter map is in a3.
942 MemOperand unmapped_location =
943 GenerateUnmappedArgumentsLookup(masm, a2, a3, t0, &slow);
944 __ lw(a1, unmapped_location);
945 __ LoadRoot(a3, Heap::kTheHoleValueRootIndex);
946 __ Branch(&slow, eq, a1, Operand(a3));
947 GenerateFunctionTailCall(masm, argc, &slow, a3);
948 __ bind(&slow);
949 GenerateMiss(masm, argc);
950 }
951
952
953 Object* KeyedLoadIC_Miss(Arguments args);
954
955
895 void KeyedLoadIC::GenerateMiss(MacroAssembler* masm, bool force_generic) { 956 void KeyedLoadIC::GenerateMiss(MacroAssembler* masm, bool force_generic) {
896 // ---------- S t a t e -------------- 957 // ---------- S t a t e --------------
897 // -- ra : return address 958 // -- ra : return address
898 // -- a0 : key 959 // -- a0 : key
899 // -- a1 : receiver 960 // -- a1 : receiver
900 // ----------------------------------- 961 // -----------------------------------
901 Isolate* isolate = masm->isolate(); 962 Isolate* isolate = masm->isolate();
902 963
903 __ IncrementCounter(isolate->counters()->keyed_load_miss(), 1, a3, t0); 964 __ IncrementCounter(isolate->counters()->keyed_load_miss(), 1, a3, t0);
904 965
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
942 1003
943 // Check that the key is a smi. 1004 // Check that the key is a smi.
944 __ JumpIfNotSmi(key, &check_string); 1005 __ JumpIfNotSmi(key, &check_string);
945 __ bind(&index_smi); 1006 __ bind(&index_smi);
946 // Now the key is known to be a smi. This place is also jumped to from below 1007 // Now the key is known to be a smi. This place is also jumped to from below
947 // where a numeric string is converted to a smi. 1008 // where a numeric string is converted to a smi.
948 1009
949 GenerateKeyedLoadReceiverCheck( 1010 GenerateKeyedLoadReceiverCheck(
950 masm, receiver, a2, a3, Map::kHasIndexedInterceptor, &slow); 1011 masm, receiver, a2, a3, Map::kHasIndexedInterceptor, &slow);
951 1012
952 // Check the "has fast elements" bit in the receiver's map which is 1013 // Check the receiver's map to see if it has fast elements.
953 // now in a2. 1014 __ CheckFastElements(a2, a3, &check_number_dictionary);
954 __ lbu(a3, FieldMemOperand(a2, Map::kBitField2Offset));
955 __ And(at, a3, Operand(1 << Map::kHasFastElements));
956 __ Branch(&check_number_dictionary, eq, at, Operand(zero_reg));
957 1015
958 GenerateFastArrayLoad( 1016 GenerateFastArrayLoad(
959 masm, receiver, key, t0, a3, a2, v0, NULL, &slow); 1017 masm, receiver, key, t0, a3, a2, v0, NULL, &slow);
960 1018
961 __ IncrementCounter(isolate->counters()->keyed_load_generic_smi(), 1, a2, a3); 1019 __ IncrementCounter(isolate->counters()->keyed_load_generic_smi(), 1, a2, a3);
962 __ Ret(); 1020 __ Ret();
963 1021
964 __ bind(&check_number_dictionary); 1022 __ bind(&check_number_dictionary);
965 __ lw(t0, FieldMemOperand(receiver, JSObject::kElementsOffset)); 1023 __ lw(t0, FieldMemOperand(receiver, JSObject::kElementsOffset));
966 __ lw(a3, FieldMemOperand(t0, JSObject::kMapOffset)); 1024 __ lw(a3, FieldMemOperand(t0, JSObject::kMapOffset));
967 1025
968 // Check whether the elements is a number dictionary. 1026 // Check whether the elements is a number dictionary.
969 // a0: key 1027 // a0: key
970 // a3: elements map 1028 // a3: elements map
971 // t0: elements 1029 // t0: elements
972 __ LoadRoot(at, Heap::kHashTableMapRootIndex); 1030 __ LoadRoot(at, Heap::kHashTableMapRootIndex);
973 __ Branch(&slow, ne, a3, Operand(at)); 1031 __ Branch(&slow, ne, a3, Operand(at));
974 __ sra(a2, a0, kSmiTagSize); 1032 __ sra(a2, a0, kSmiTagSize);
975 GenerateNumberDictionaryLoad(masm, &slow, t0, a0, v0, a2, a3, t1); 1033 __ LoadFromNumberDictionary(&slow, t0, a0, v0, a2, a3, t1);
976 __ Ret(); 1034 __ Ret();
977 1035
978 // Slow case, key and receiver still in a0 and a1. 1036 // Slow case, key and receiver still in a0 and a1.
979 __ bind(&slow); 1037 __ bind(&slow);
980 __ IncrementCounter(isolate->counters()->keyed_load_generic_slow(), 1038 __ IncrementCounter(isolate->counters()->keyed_load_generic_slow(),
981 1, 1039 1,
982 a2, 1040 a2,
983 a3); 1041 a3);
984 GenerateRuntimeGetProperty(masm); 1042 GenerateRuntimeGetProperty(masm);
985 1043
(...skipping 180 matching lines...) Expand 10 before | Expand all | Expand 10 after
1166 __ lw(t3, FieldMemOperand(receiver, HeapObject::kMapOffset)); 1224 __ lw(t3, FieldMemOperand(receiver, HeapObject::kMapOffset));
1167 // Check that the receiver does not require access checks. We need 1225 // Check that the receiver does not require access checks. We need
1168 // to do this because this generic stub does not perform map checks. 1226 // to do this because this generic stub does not perform map checks.
1169 __ lbu(t0, FieldMemOperand(t3, Map::kBitFieldOffset)); 1227 __ lbu(t0, FieldMemOperand(t3, Map::kBitFieldOffset));
1170 __ And(t0, t0, Operand(1 << Map::kIsAccessCheckNeeded)); 1228 __ And(t0, t0, Operand(1 << Map::kIsAccessCheckNeeded));
1171 __ Branch(&slow, ne, t0, Operand(zero_reg)); 1229 __ Branch(&slow, ne, t0, Operand(zero_reg));
1172 // Check if the object is a JS array or not. 1230 // Check if the object is a JS array or not.
1173 __ lbu(t3, FieldMemOperand(t3, Map::kInstanceTypeOffset)); 1231 __ lbu(t3, FieldMemOperand(t3, Map::kInstanceTypeOffset));
1174 1232
1175 __ Branch(&array, eq, t3, Operand(JS_ARRAY_TYPE)); 1233 __ Branch(&array, eq, t3, Operand(JS_ARRAY_TYPE));
1176 // Check that the object is some kind of JS object. 1234 // Check that the object is some kind of JSObject.
1177 __ Branch(&slow, lt, t3, Operand(FIRST_JS_OBJECT_TYPE)); 1235 __ Branch(&slow, lt, t3, Operand(FIRST_JS_RECEIVER_TYPE));
1236 __ Branch(&slow, eq, t3, Operand(JS_PROXY_TYPE));
1237 __ Branch(&slow, eq, t3, Operand(JS_FUNCTION_PROXY_TYPE));
1178 1238
1179 // Object case: Check key against length in the elements array. 1239 // Object case: Check key against length in the elements array.
1180 __ lw(elements, FieldMemOperand(receiver, JSObject::kElementsOffset)); 1240 __ lw(elements, FieldMemOperand(receiver, JSObject::kElementsOffset));
1181 // Check that the object is in fast mode and writable. 1241 // Check that the object is in fast mode and writable.
1182 __ lw(t3, FieldMemOperand(elements, HeapObject::kMapOffset)); 1242 __ lw(t3, FieldMemOperand(elements, HeapObject::kMapOffset));
1183 __ LoadRoot(t0, Heap::kFixedArrayMapRootIndex); 1243 __ LoadRoot(t0, Heap::kFixedArrayMapRootIndex);
1184 __ Branch(&slow, ne, t3, Operand(t0)); 1244 __ Branch(&slow, ne, t3, Operand(t0));
1185 // Check array bounds. Both the key and the length of FixedArray are smis. 1245 // Check array bounds. Both the key and the length of FixedArray are smis.
1186 __ lw(t0, FieldMemOperand(elements, FixedArray::kLengthOffset)); 1246 __ lw(t0, FieldMemOperand(elements, FixedArray::kLengthOffset));
1187 __ Branch(&fast, lo, key, Operand(t0)); 1247 __ Branch(&fast, lo, key, Operand(t0));
(...skipping 383 matching lines...) Expand 10 before | Expand all | Expand 10 after
1571 Register reg = Register::from_code(Assembler::GetRs(instr_at_patch)); 1631 Register reg = Register::from_code(Assembler::GetRs(instr_at_patch));
1572 patcher.masm()->andi(at, reg, kSmiTagMask); 1632 patcher.masm()->andi(at, reg, kSmiTagMask);
1573 patcher.ChangeBranchCondition(eq); 1633 patcher.ChangeBranchCondition(eq);
1574 } 1634 }
1575 } 1635 }
1576 1636
1577 1637
1578 } } // namespace v8::internal 1638 } } // namespace v8::internal
1579 1639
1580 #endif // V8_TARGET_ARCH_MIPS 1640 #endif // V8_TARGET_ARCH_MIPS
OLDNEW
« no previous file with comments | « src/mips/full-codegen-mips.cc ('k') | src/mips/macro-assembler-mips.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698