| OLD | NEW |
| 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/bootstrapper.h" | 9 #include "src/bootstrapper.h" |
| 10 #include "src/code-stubs.h" | 10 #include "src/code-stubs.h" |
| (...skipping 2439 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2450 __ SmiUntag(x1, x10); | 2450 __ SmiUntag(x1, x10); |
| 2451 | 2451 |
| 2452 // The third bit determines the string encoding in string_type. | 2452 // The third bit determines the string encoding in string_type. |
| 2453 STATIC_ASSERT(kOneByteStringTag == 0x04); | 2453 STATIC_ASSERT(kOneByteStringTag == 0x04); |
| 2454 STATIC_ASSERT(kTwoByteStringTag == 0x00); | 2454 STATIC_ASSERT(kTwoByteStringTag == 0x00); |
| 2455 STATIC_ASSERT(kStringEncodingMask == 0x04); | 2455 STATIC_ASSERT(kStringEncodingMask == 0x04); |
| 2456 | 2456 |
| 2457 // Find the code object based on the assumptions above. | 2457 // Find the code object based on the assumptions above. |
| 2458 // kDataOneByteCodeOffset and kDataUC16CodeOffset are adjacent, adds an offset | 2458 // kDataOneByteCodeOffset and kDataUC16CodeOffset are adjacent, adds an offset |
| 2459 // of kPointerSize to reach the latter. | 2459 // of kPointerSize to reach the latter. |
| 2460 DCHECK_EQ(JSRegExp::kDataOneByteCodeOffset + kPointerSize, | 2460 STATIC_ASSERT(JSRegExp::kDataOneByteCodeOffset + kPointerSize == |
| 2461 JSRegExp::kDataUC16CodeOffset); | 2461 JSRegExp::kDataUC16CodeOffset); |
| 2462 __ Mov(x10, kPointerSize); | 2462 __ Mov(x10, kPointerSize); |
| 2463 // We will need the encoding later: Latin1 = 0x04 | 2463 // We will need the encoding later: Latin1 = 0x04 |
| 2464 // UC16 = 0x00 | 2464 // UC16 = 0x00 |
| 2465 __ Ands(string_encoding, string_type, kStringEncodingMask); | 2465 __ Ands(string_encoding, string_type, kStringEncodingMask); |
| 2466 __ CzeroX(x10, ne); | 2466 __ CzeroX(x10, ne); |
| 2467 __ Add(x10, regexp_data, x10); | 2467 __ Add(x10, regexp_data, x10); |
| 2468 __ Ldr(code_object, FieldMemOperand(x10, JSRegExp::kDataOneByteCodeOffset)); | 2468 __ Ldr(code_object, FieldMemOperand(x10, JSRegExp::kDataOneByteCodeOffset)); |
| 2469 | 2469 |
| 2470 // (E) Carry on. String handling is done. | 2470 // (E) Carry on. String handling is done. |
| 2471 | 2471 |
| (...skipping 2468 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4940 // the hash in a separate instruction. The value hash + i + i * i is right | 4940 // the hash in a separate instruction. The value hash + i + i * i is right |
| 4941 // shifted in the following and instruction. | 4941 // shifted in the following and instruction. |
| 4942 DCHECK(NameDictionary::GetProbeOffset(i) < | 4942 DCHECK(NameDictionary::GetProbeOffset(i) < |
| 4943 1 << (32 - Name::kHashFieldOffset)); | 4943 1 << (32 - Name::kHashFieldOffset)); |
| 4944 __ Add(scratch2, scratch2, Operand( | 4944 __ Add(scratch2, scratch2, Operand( |
| 4945 NameDictionary::GetProbeOffset(i) << Name::kHashShift)); | 4945 NameDictionary::GetProbeOffset(i) << Name::kHashShift)); |
| 4946 } | 4946 } |
| 4947 __ And(scratch2, scratch1, Operand(scratch2, LSR, Name::kHashShift)); | 4947 __ And(scratch2, scratch1, Operand(scratch2, LSR, Name::kHashShift)); |
| 4948 | 4948 |
| 4949 // Scale the index by multiplying by the element size. | 4949 // Scale the index by multiplying by the element size. |
| 4950 DCHECK(NameDictionary::kEntrySize == 3); | 4950 STATIC_ASSERT(NameDictionary::kEntrySize == 3); |
| 4951 __ Add(scratch2, scratch2, Operand(scratch2, LSL, 1)); | 4951 __ Add(scratch2, scratch2, Operand(scratch2, LSL, 1)); |
| 4952 | 4952 |
| 4953 // Check if the key is identical to the name. | 4953 // Check if the key is identical to the name. |
| 4954 UseScratchRegisterScope temps(masm); | 4954 UseScratchRegisterScope temps(masm); |
| 4955 Register scratch3 = temps.AcquireX(); | 4955 Register scratch3 = temps.AcquireX(); |
| 4956 __ Add(scratch2, elements, Operand(scratch2, LSL, kPointerSizeLog2)); | 4956 __ Add(scratch2, elements, Operand(scratch2, LSL, kPointerSizeLog2)); |
| 4957 __ Ldr(scratch3, FieldMemOperand(scratch2, kElementsStartOffset)); | 4957 __ Ldr(scratch3, FieldMemOperand(scratch2, kElementsStartOffset)); |
| 4958 __ Cmp(name, scratch3); | 4958 __ Cmp(name, scratch3); |
| 4959 __ B(eq, done); | 4959 __ B(eq, done); |
| 4960 } | 4960 } |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5009 for (int i = 0; i < kInlinedProbes; i++) { | 5009 for (int i = 0; i < kInlinedProbes; i++) { |
| 5010 // scratch0 points to properties hash. | 5010 // scratch0 points to properties hash. |
| 5011 // Compute the masked index: (hash + i + i * i) & mask. | 5011 // Compute the masked index: (hash + i + i * i) & mask. |
| 5012 Register index = scratch0; | 5012 Register index = scratch0; |
| 5013 // Capacity is smi 2^n. | 5013 // Capacity is smi 2^n. |
| 5014 __ Ldrsw(index, UntagSmiFieldMemOperand(properties, kCapacityOffset)); | 5014 __ Ldrsw(index, UntagSmiFieldMemOperand(properties, kCapacityOffset)); |
| 5015 __ Sub(index, index, 1); | 5015 __ Sub(index, index, 1); |
| 5016 __ And(index, index, name->Hash() + NameDictionary::GetProbeOffset(i)); | 5016 __ And(index, index, name->Hash() + NameDictionary::GetProbeOffset(i)); |
| 5017 | 5017 |
| 5018 // Scale the index by multiplying by the entry size. | 5018 // Scale the index by multiplying by the entry size. |
| 5019 DCHECK(NameDictionary::kEntrySize == 3); | 5019 STATIC_ASSERT(NameDictionary::kEntrySize == 3); |
| 5020 __ Add(index, index, Operand(index, LSL, 1)); // index *= 3. | 5020 __ Add(index, index, Operand(index, LSL, 1)); // index *= 3. |
| 5021 | 5021 |
| 5022 Register entity_name = scratch0; | 5022 Register entity_name = scratch0; |
| 5023 // Having undefined at this place means the name is not contained. | 5023 // Having undefined at this place means the name is not contained. |
| 5024 Register tmp = index; | 5024 Register tmp = index; |
| 5025 __ Add(tmp, properties, Operand(index, LSL, kPointerSizeLog2)); | 5025 __ Add(tmp, properties, Operand(index, LSL, kPointerSizeLog2)); |
| 5026 __ Ldr(entity_name, FieldMemOperand(tmp, kElementsStartOffset)); | 5026 __ Ldr(entity_name, FieldMemOperand(tmp, kElementsStartOffset)); |
| 5027 | 5027 |
| 5028 __ JumpIfRoot(entity_name, Heap::kUndefinedValueRootIndex, done); | 5028 __ JumpIfRoot(entity_name, Heap::kUndefinedValueRootIndex, done); |
| 5029 | 5029 |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5100 DCHECK(NameDictionary::GetProbeOffset(i) < | 5100 DCHECK(NameDictionary::GetProbeOffset(i) < |
| 5101 1 << (32 - Name::kHashFieldOffset)); | 5101 1 << (32 - Name::kHashFieldOffset)); |
| 5102 __ Add(index, hash, | 5102 __ Add(index, hash, |
| 5103 NameDictionary::GetProbeOffset(i) << Name::kHashShift); | 5103 NameDictionary::GetProbeOffset(i) << Name::kHashShift); |
| 5104 } else { | 5104 } else { |
| 5105 __ Mov(index, hash); | 5105 __ Mov(index, hash); |
| 5106 } | 5106 } |
| 5107 __ And(index, mask, Operand(index, LSR, Name::kHashShift)); | 5107 __ And(index, mask, Operand(index, LSR, Name::kHashShift)); |
| 5108 | 5108 |
| 5109 // Scale the index by multiplying by the entry size. | 5109 // Scale the index by multiplying by the entry size. |
| 5110 DCHECK(NameDictionary::kEntrySize == 3); | 5110 STATIC_ASSERT(NameDictionary::kEntrySize == 3); |
| 5111 __ Add(index, index, Operand(index, LSL, 1)); // index *= 3. | 5111 __ Add(index, index, Operand(index, LSL, 1)); // index *= 3. |
| 5112 | 5112 |
| 5113 __ Add(index, dictionary, Operand(index, LSL, kPointerSizeLog2)); | 5113 __ Add(index, dictionary, Operand(index, LSL, kPointerSizeLog2)); |
| 5114 __ Ldr(entry_key, FieldMemOperand(index, kElementsStartOffset)); | 5114 __ Ldr(entry_key, FieldMemOperand(index, kElementsStartOffset)); |
| 5115 | 5115 |
| 5116 // Having undefined at this place means the name is not contained. | 5116 // Having undefined at this place means the name is not contained. |
| 5117 __ Cmp(entry_key, undefined); | 5117 __ Cmp(entry_key, undefined); |
| 5118 __ B(eq, ¬_in_dictionary); | 5118 __ B(eq, ¬_in_dictionary); |
| 5119 | 5119 |
| 5120 // Stop if found the property. | 5120 // Stop if found the property. |
| (...skipping 723 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5844 MemOperand(fp, 6 * kPointerSize), NULL); | 5844 MemOperand(fp, 6 * kPointerSize), NULL); |
| 5845 } | 5845 } |
| 5846 | 5846 |
| 5847 | 5847 |
| 5848 #undef __ | 5848 #undef __ |
| 5849 | 5849 |
| 5850 } // namespace internal | 5850 } // namespace internal |
| 5851 } // namespace v8 | 5851 } // namespace v8 |
| 5852 | 5852 |
| 5853 #endif // V8_TARGET_ARCH_ARM64 | 5853 #endif // V8_TARGET_ARCH_ARM64 |
| OLD | NEW |