| 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 |