OLD | NEW |
1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
134 scratch1, | 134 scratch1, |
135 scratch2); | 135 scratch2); |
136 | 136 |
137 // If probing finds an entry check that the value is a normal property. | 137 // If probing finds an entry check that the value is a normal property. |
138 __ Bind(&done); | 138 __ Bind(&done); |
139 | 139 |
140 static const int kElementsStartOffset = NameDictionary::kHeaderSize + | 140 static const int kElementsStartOffset = NameDictionary::kHeaderSize + |
141 NameDictionary::kElementsStartIndex * kPointerSize; | 141 NameDictionary::kElementsStartIndex * kPointerSize; |
142 static const int kDetailsOffset = kElementsStartOffset + 2 * kPointerSize; | 142 static const int kDetailsOffset = kElementsStartOffset + 2 * kPointerSize; |
143 __ Ldr(scratch1, FieldMemOperand(scratch2, kDetailsOffset)); | 143 __ Ldr(scratch1, FieldMemOperand(scratch2, kDetailsOffset)); |
144 __ Tst(scratch1, Operand(Smi::FromInt(PropertyDetails::TypeField::kMask))); | 144 __ Tst(scratch1, Smi::FromInt(PropertyDetails::TypeField::kMask)); |
145 __ B(ne, miss); | 145 __ B(ne, miss); |
146 | 146 |
147 // Get the value at the masked, scaled index and return. | 147 // Get the value at the masked, scaled index and return. |
148 __ Ldr(result, | 148 __ Ldr(result, |
149 FieldMemOperand(scratch2, kElementsStartOffset + 1 * kPointerSize)); | 149 FieldMemOperand(scratch2, kElementsStartOffset + 1 * kPointerSize)); |
150 } | 150 } |
151 | 151 |
152 | 152 |
153 // Helper function used from StoreIC::GenerateNormal. | 153 // Helper function used from StoreIC::GenerateNormal. |
154 // | 154 // |
(...skipping 214 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
369 __ Tbnz(key, kXSignBit, slow_case); | 369 __ Tbnz(key, kXSignBit, slow_case); |
370 | 370 |
371 // Load the elements object and check its map. | 371 // Load the elements object and check its map. |
372 Handle<Map> arguments_map(heap->sloppy_arguments_elements_map()); | 372 Handle<Map> arguments_map(heap->sloppy_arguments_elements_map()); |
373 __ Ldr(map, FieldMemOperand(object, JSObject::kElementsOffset)); | 373 __ Ldr(map, FieldMemOperand(object, JSObject::kElementsOffset)); |
374 __ CheckMap(map, scratch1, arguments_map, slow_case, DONT_DO_SMI_CHECK); | 374 __ CheckMap(map, scratch1, arguments_map, slow_case, DONT_DO_SMI_CHECK); |
375 | 375 |
376 // Check if element is in the range of mapped arguments. If not, jump | 376 // Check if element is in the range of mapped arguments. If not, jump |
377 // to the unmapped lookup. | 377 // to the unmapped lookup. |
378 __ Ldr(scratch1, FieldMemOperand(map, FixedArray::kLengthOffset)); | 378 __ Ldr(scratch1, FieldMemOperand(map, FixedArray::kLengthOffset)); |
379 __ Sub(scratch1, scratch1, Operand(Smi::FromInt(2))); | 379 __ Sub(scratch1, scratch1, Smi::FromInt(2)); |
380 __ Cmp(key, scratch1); | 380 __ Cmp(key, scratch1); |
381 __ B(hs, unmapped_case); | 381 __ B(hs, unmapped_case); |
382 | 382 |
383 // Load element index and check whether it is the hole. | 383 // Load element index and check whether it is the hole. |
384 static const int offset = | 384 static const int offset = |
385 FixedArray::kHeaderSize + 2 * kPointerSize - kHeapObjectTag; | 385 FixedArray::kHeaderSize + 2 * kPointerSize - kHeapObjectTag; |
386 | 386 |
387 __ Add(scratch1, map, offset); | 387 __ Add(scratch1, map, offset); |
388 __ SmiUntag(scratch2, key); | 388 __ SmiUntag(scratch2, key); |
389 __ Ldr(scratch1, MemOperand(scratch1, scratch2, LSL, kPointerSizeLog2)); | 389 __ Ldr(scratch1, MemOperand(scratch1, scratch2, LSL, kPointerSizeLog2)); |
(...skipping 305 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
695 __ And(scratch2, scratch2, mask); | 695 __ And(scratch2, scratch2, mask); |
696 | 696 |
697 // Load the key (consisting of map and unique name) from the cache and | 697 // Load the key (consisting of map and unique name) from the cache and |
698 // check for match. | 698 // check for match. |
699 Label load_in_object_property; | 699 Label load_in_object_property; |
700 static const int kEntriesPerBucket = KeyedLookupCache::kEntriesPerBucket; | 700 static const int kEntriesPerBucket = KeyedLookupCache::kEntriesPerBucket; |
701 Label hit_on_nth_entry[kEntriesPerBucket]; | 701 Label hit_on_nth_entry[kEntriesPerBucket]; |
702 ExternalReference cache_keys = | 702 ExternalReference cache_keys = |
703 ExternalReference::keyed_lookup_cache_keys(isolate); | 703 ExternalReference::keyed_lookup_cache_keys(isolate); |
704 | 704 |
705 __ Mov(scratch3, Operand(cache_keys)); | 705 __ Mov(scratch3, cache_keys); |
706 __ Add(scratch3, scratch3, Operand(scratch2, LSL, kPointerSizeLog2 + 1)); | 706 __ Add(scratch3, scratch3, Operand(scratch2, LSL, kPointerSizeLog2 + 1)); |
707 | 707 |
708 for (int i = 0; i < kEntriesPerBucket - 1; i++) { | 708 for (int i = 0; i < kEntriesPerBucket - 1; i++) { |
709 Label try_next_entry; | 709 Label try_next_entry; |
710 // Load map and make scratch3 pointing to the next entry. | 710 // Load map and make scratch3 pointing to the next entry. |
711 __ Ldr(scratch4, MemOperand(scratch3, kPointerSize * 2, PostIndex)); | 711 __ Ldr(scratch4, MemOperand(scratch3, kPointerSize * 2, PostIndex)); |
712 __ Cmp(receiver_map, scratch4); | 712 __ Cmp(receiver_map, scratch4); |
713 __ B(ne, &try_next_entry); | 713 __ B(ne, &try_next_entry); |
714 __ Ldr(scratch4, MemOperand(scratch3, -kPointerSize)); // Load name | 714 __ Ldr(scratch4, MemOperand(scratch3, -kPointerSize)); // Load name |
715 __ Cmp(key, scratch4); | 715 __ Cmp(key, scratch4); |
716 __ B(eq, &hit_on_nth_entry[i]); | 716 __ B(eq, &hit_on_nth_entry[i]); |
717 __ Bind(&try_next_entry); | 717 __ Bind(&try_next_entry); |
718 } | 718 } |
719 | 719 |
720 // Last entry. | 720 // Last entry. |
721 __ Ldr(scratch4, MemOperand(scratch3, kPointerSize, PostIndex)); | 721 __ Ldr(scratch4, MemOperand(scratch3, kPointerSize, PostIndex)); |
722 __ Cmp(receiver_map, scratch4); | 722 __ Cmp(receiver_map, scratch4); |
723 __ B(ne, slow); | 723 __ B(ne, slow); |
724 __ Ldr(scratch4, MemOperand(scratch3)); | 724 __ Ldr(scratch4, MemOperand(scratch3)); |
725 __ Cmp(key, scratch4); | 725 __ Cmp(key, scratch4); |
726 __ B(ne, slow); | 726 __ B(ne, slow); |
727 | 727 |
728 // Get field offset. | 728 // Get field offset. |
729 ExternalReference cache_field_offsets = | 729 ExternalReference cache_field_offsets = |
730 ExternalReference::keyed_lookup_cache_field_offsets(isolate); | 730 ExternalReference::keyed_lookup_cache_field_offsets(isolate); |
731 | 731 |
732 // Hit on nth entry. | 732 // Hit on nth entry. |
733 for (int i = kEntriesPerBucket - 1; i >= 0; i--) { | 733 for (int i = kEntriesPerBucket - 1; i >= 0; i--) { |
734 __ Bind(&hit_on_nth_entry[i]); | 734 __ Bind(&hit_on_nth_entry[i]); |
735 __ Mov(scratch3, Operand(cache_field_offsets)); | 735 __ Mov(scratch3, cache_field_offsets); |
736 if (i != 0) { | 736 if (i != 0) { |
737 __ Add(scratch2, scratch2, i); | 737 __ Add(scratch2, scratch2, i); |
738 } | 738 } |
739 __ Ldr(scratch4.W(), MemOperand(scratch3, scratch2, LSL, 2)); | 739 __ Ldr(scratch4.W(), MemOperand(scratch3, scratch2, LSL, 2)); |
740 __ Ldrb(scratch5, | 740 __ Ldrb(scratch5, |
741 FieldMemOperand(receiver_map, Map::kInObjectPropertiesOffset)); | 741 FieldMemOperand(receiver_map, Map::kInObjectPropertiesOffset)); |
742 __ Subs(scratch4, scratch4, scratch5); | 742 __ Subs(scratch4, scratch4, scratch5); |
743 __ B(ge, &property_array_property); | 743 __ B(ge, &property_array_property); |
744 if (i != 0) { | 744 if (i != 0) { |
745 __ B(&load_in_object_property); | 745 __ B(&load_in_object_property); |
(...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
932 // -- x1 : key | 932 // -- x1 : key |
933 // -- x2 : receiver | 933 // -- x2 : receiver |
934 // -- lr : return address | 934 // -- lr : return address |
935 // ----------------------------------- | 935 // ----------------------------------- |
936 | 936 |
937 // Push receiver, key and value for runtime call. | 937 // Push receiver, key and value for runtime call. |
938 __ Push(x2, x1, x0); | 938 __ Push(x2, x1, x0); |
939 | 939 |
940 // Push PropertyAttributes(NONE) and strict_mode for runtime call. | 940 // Push PropertyAttributes(NONE) and strict_mode for runtime call. |
941 STATIC_ASSERT(NONE == 0); | 941 STATIC_ASSERT(NONE == 0); |
942 __ Mov(x10, Operand(Smi::FromInt(strict_mode))); | 942 __ Mov(x10, Smi::FromInt(strict_mode)); |
943 __ Push(xzr, x10); | 943 __ Push(xzr, x10); |
944 | 944 |
945 __ TailCallRuntime(Runtime::kSetProperty, 5, 1); | 945 __ TailCallRuntime(Runtime::kSetProperty, 5, 1); |
946 } | 946 } |
947 | 947 |
948 | 948 |
949 static void KeyedStoreGenerateGenericHelper( | 949 static void KeyedStoreGenerateGenericHelper( |
950 MacroAssembler* masm, | 950 MacroAssembler* masm, |
951 Label* fast_object, | 951 Label* fast_object, |
952 Label* fast_double, | 952 Label* fast_double, |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
989 | 989 |
990 // Smi stores don't require further checks. | 990 // Smi stores don't require further checks. |
991 __ JumpIfSmi(value, &finish_store); | 991 __ JumpIfSmi(value, &finish_store); |
992 | 992 |
993 // Escape to elements kind transition case. | 993 // Escape to elements kind transition case. |
994 __ CheckFastObjectElements(receiver_map, x10, &transition_smi_elements); | 994 __ CheckFastObjectElements(receiver_map, x10, &transition_smi_elements); |
995 | 995 |
996 __ Bind(&finish_store); | 996 __ Bind(&finish_store); |
997 if (increment_length == kIncrementLength) { | 997 if (increment_length == kIncrementLength) { |
998 // Add 1 to receiver->length. | 998 // Add 1 to receiver->length. |
999 __ Add(x10, key, Operand(Smi::FromInt(1))); | 999 __ Add(x10, key, Smi::FromInt(1)); |
1000 __ Str(x10, FieldMemOperand(receiver, JSArray::kLengthOffset)); | 1000 __ Str(x10, FieldMemOperand(receiver, JSArray::kLengthOffset)); |
1001 } | 1001 } |
1002 | 1002 |
1003 Register address = x11; | 1003 Register address = x11; |
1004 __ Add(address, elements, FixedArray::kHeaderSize - kHeapObjectTag); | 1004 __ Add(address, elements, FixedArray::kHeaderSize - kHeapObjectTag); |
1005 __ Add(address, address, Operand::UntagSmiAndScale(key, kPointerSizeLog2)); | 1005 __ Add(address, address, Operand::UntagSmiAndScale(key, kPointerSizeLog2)); |
1006 __ Str(value, MemOperand(address)); | 1006 __ Str(value, MemOperand(address)); |
1007 | 1007 |
1008 Label dont_record_write; | 1008 Label dont_record_write; |
1009 __ JumpIfSmi(value, &dont_record_write); | 1009 __ JumpIfSmi(value, &dont_record_write); |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1041 __ Bind(&fast_double_without_map_check); | 1041 __ Bind(&fast_double_without_map_check); |
1042 __ StoreNumberToDoubleElements(value, | 1042 __ StoreNumberToDoubleElements(value, |
1043 key, | 1043 key, |
1044 elements, | 1044 elements, |
1045 x10, | 1045 x10, |
1046 d0, | 1046 d0, |
1047 d1, | 1047 d1, |
1048 &transition_double_elements); | 1048 &transition_double_elements); |
1049 if (increment_length == kIncrementLength) { | 1049 if (increment_length == kIncrementLength) { |
1050 // Add 1 to receiver->length. | 1050 // Add 1 to receiver->length. |
1051 __ Add(x10, key, Operand(Smi::FromInt(1))); | 1051 __ Add(x10, key, Smi::FromInt(1)); |
1052 __ Str(x10, FieldMemOperand(receiver, JSArray::kLengthOffset)); | 1052 __ Str(x10, FieldMemOperand(receiver, JSArray::kLengthOffset)); |
1053 } | 1053 } |
1054 __ Ret(); | 1054 __ Ret(); |
1055 | 1055 |
1056 | 1056 |
1057 __ Bind(&transition_smi_elements); | 1057 __ Bind(&transition_smi_elements); |
1058 // Transition the array appropriately depending on the value type. | 1058 // Transition the array appropriately depending on the value type. |
1059 __ Ldr(x10, FieldMemOperand(value, HeapObject::kMapOffset)); | 1059 __ Ldr(x10, FieldMemOperand(value, HeapObject::kMapOffset)); |
1060 __ JumpIfNotRoot(x10, Heap::kHeapNumberMapRootIndex, &non_double_value); | 1060 __ JumpIfNotRoot(x10, Heap::kHeapNumberMapRootIndex, &non_double_value); |
1061 | 1061 |
(...skipping 216 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1278 ASM_LOCATION("StoreIC::GenerateRuntimeSetProperty"); | 1278 ASM_LOCATION("StoreIC::GenerateRuntimeSetProperty"); |
1279 // ----------- S t a t e ------------- | 1279 // ----------- S t a t e ------------- |
1280 // -- x0 : value | 1280 // -- x0 : value |
1281 // -- x1 : receiver | 1281 // -- x1 : receiver |
1282 // -- x2 : name | 1282 // -- x2 : name |
1283 // -- lr : return address | 1283 // -- lr : return address |
1284 // ----------------------------------- | 1284 // ----------------------------------- |
1285 | 1285 |
1286 __ Push(x1, x2, x0); | 1286 __ Push(x1, x2, x0); |
1287 | 1287 |
1288 __ Mov(x11, Operand(Smi::FromInt(NONE))); // PropertyAttributes | 1288 __ Mov(x11, Smi::FromInt(NONE)); // PropertyAttributes |
1289 __ Mov(x10, Operand(Smi::FromInt(strict_mode))); | 1289 __ Mov(x10, Smi::FromInt(strict_mode)); |
1290 __ Push(x11, x10); | 1290 __ Push(x11, x10); |
1291 | 1291 |
1292 // Do tail-call to runtime routine. | 1292 // Do tail-call to runtime routine. |
1293 __ TailCallRuntime(Runtime::kSetProperty, 5, 1); | 1293 __ TailCallRuntime(Runtime::kSetProperty, 5, 1); |
1294 } | 1294 } |
1295 | 1295 |
1296 | 1296 |
1297 void StoreIC::GenerateSlow(MacroAssembler* masm) { | 1297 void StoreIC::GenerateSlow(MacroAssembler* masm) { |
1298 // ---------- S t a t e -------------- | 1298 // ---------- S t a t e -------------- |
1299 // -- x0 : value | 1299 // -- x0 : value |
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1398 ASSERT(to_patch->Mask(TestBranchMask) == TBNZ); | 1398 ASSERT(to_patch->Mask(TestBranchMask) == TBNZ); |
1399 // This is JumpIfSmi(smi_reg, branch_imm). | 1399 // This is JumpIfSmi(smi_reg, branch_imm). |
1400 patcher.tbz(smi_reg, 0, branch_imm); | 1400 patcher.tbz(smi_reg, 0, branch_imm); |
1401 } | 1401 } |
1402 } | 1402 } |
1403 | 1403 |
1404 | 1404 |
1405 } } // namespace v8::internal | 1405 } } // namespace v8::internal |
1406 | 1406 |
1407 #endif // V8_TARGET_ARCH_A64 | 1407 #endif // V8_TARGET_ARCH_A64 |
OLD | NEW |