| 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 #if V8_TARGET_ARCH_ARM64 | 5 #if V8_TARGET_ARCH_ARM64 |
| 6 | 6 |
| 7 #include "src/base/bits.h" | 7 #include "src/base/bits.h" |
| 8 #include "src/base/division-by-constant.h" | 8 #include "src/base/division-by-constant.h" |
| 9 #include "src/bootstrapper.h" | 9 #include "src/bootstrapper.h" |
| 10 #include "src/codegen.h" | 10 #include "src/codegen.h" |
| (...skipping 2185 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2196 B(&entry); | 2196 B(&entry); |
| 2197 Bind(&loop); | 2197 Bind(&loop); |
| 2198 Stp(filler, filler, MemOperand(current_address, 2 * kPointerSize, PostIndex)); | 2198 Stp(filler, filler, MemOperand(current_address, 2 * kPointerSize, PostIndex)); |
| 2199 Bind(&entry); | 2199 Bind(&entry); |
| 2200 Cmp(current_address, end_address); | 2200 Cmp(current_address, end_address); |
| 2201 B(lo, &loop); | 2201 B(lo, &loop); |
| 2202 | 2202 |
| 2203 Bind(&done); | 2203 Bind(&done); |
| 2204 } | 2204 } |
| 2205 | 2205 |
| 2206 | |
| 2207 void MacroAssembler::JumpIfEitherIsNotSequentialOneByteStrings( | |
| 2208 Register first, Register second, Register scratch1, Register scratch2, | |
| 2209 Label* failure, SmiCheckType smi_check) { | |
| 2210 if (smi_check == DO_SMI_CHECK) { | |
| 2211 JumpIfEitherSmi(first, second, failure); | |
| 2212 } else if (emit_debug_code()) { | |
| 2213 DCHECK(smi_check == DONT_DO_SMI_CHECK); | |
| 2214 Label not_smi; | |
| 2215 JumpIfEitherSmi(first, second, NULL, ¬_smi); | |
| 2216 | |
| 2217 // At least one input is a smi, but the flags indicated a smi check wasn't | |
| 2218 // needed. | |
| 2219 Abort(kUnexpectedSmi); | |
| 2220 | |
| 2221 Bind(¬_smi); | |
| 2222 } | |
| 2223 | |
| 2224 // Test that both first and second are sequential one-byte strings. | |
| 2225 Ldr(scratch1, FieldMemOperand(first, HeapObject::kMapOffset)); | |
| 2226 Ldr(scratch2, FieldMemOperand(second, HeapObject::kMapOffset)); | |
| 2227 Ldrb(scratch1, FieldMemOperand(scratch1, Map::kInstanceTypeOffset)); | |
| 2228 Ldrb(scratch2, FieldMemOperand(scratch2, Map::kInstanceTypeOffset)); | |
| 2229 | |
| 2230 JumpIfEitherInstanceTypeIsNotSequentialOneByte(scratch1, scratch2, scratch1, | |
| 2231 scratch2, failure); | |
| 2232 } | |
| 2233 | |
| 2234 | |
| 2235 void MacroAssembler::JumpIfEitherInstanceTypeIsNotSequentialOneByte( | |
| 2236 Register first, Register second, Register scratch1, Register scratch2, | |
| 2237 Label* failure) { | |
| 2238 DCHECK(!AreAliased(scratch1, second)); | |
| 2239 DCHECK(!AreAliased(scratch1, scratch2)); | |
| 2240 const int kFlatOneByteStringMask = | |
| 2241 kIsNotStringMask | kStringEncodingMask | kStringRepresentationMask; | |
| 2242 const int kFlatOneByteStringTag = | |
| 2243 kStringTag | kOneByteStringTag | kSeqStringTag; | |
| 2244 And(scratch1, first, kFlatOneByteStringMask); | |
| 2245 And(scratch2, second, kFlatOneByteStringMask); | |
| 2246 Cmp(scratch1, kFlatOneByteStringTag); | |
| 2247 Ccmp(scratch2, kFlatOneByteStringTag, NoFlag, eq); | |
| 2248 B(ne, failure); | |
| 2249 } | |
| 2250 | |
| 2251 | |
| 2252 void MacroAssembler::JumpIfInstanceTypeIsNotSequentialOneByte(Register type, | |
| 2253 Register scratch, | |
| 2254 Label* failure) { | |
| 2255 const int kFlatOneByteStringMask = | |
| 2256 kIsNotStringMask | kStringEncodingMask | kStringRepresentationMask; | |
| 2257 const int kFlatOneByteStringTag = | |
| 2258 kStringTag | kOneByteStringTag | kSeqStringTag; | |
| 2259 And(scratch, type, kFlatOneByteStringMask); | |
| 2260 Cmp(scratch, kFlatOneByteStringTag); | |
| 2261 B(ne, failure); | |
| 2262 } | |
| 2263 | |
| 2264 | |
| 2265 void MacroAssembler::JumpIfBothInstanceTypesAreNotSequentialOneByte( | 2206 void MacroAssembler::JumpIfBothInstanceTypesAreNotSequentialOneByte( |
| 2266 Register first, Register second, Register scratch1, Register scratch2, | 2207 Register first, Register second, Register scratch1, Register scratch2, |
| 2267 Label* failure) { | 2208 Label* failure) { |
| 2268 DCHECK(!AreAliased(first, second, scratch1, scratch2)); | 2209 DCHECK(!AreAliased(first, second, scratch1, scratch2)); |
| 2269 const int kFlatOneByteStringMask = | 2210 const int kFlatOneByteStringMask = |
| 2270 kIsNotStringMask | kStringEncodingMask | kStringRepresentationMask; | 2211 kIsNotStringMask | kStringEncodingMask | kStringRepresentationMask; |
| 2271 const int kFlatOneByteStringTag = | 2212 const int kFlatOneByteStringTag = |
| 2272 kStringTag | kOneByteStringTag | kSeqStringTag; | 2213 kStringTag | kOneByteStringTag | kSeqStringTag; |
| 2273 And(scratch1, first, kFlatOneByteStringMask); | 2214 And(scratch1, first, kFlatOneByteStringMask); |
| 2274 And(scratch2, second, kFlatOneByteStringMask); | 2215 And(scratch2, second, kFlatOneByteStringMask); |
| (...skipping 926 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3201 Str(result_end, MemOperand(top_address)); | 3142 Str(result_end, MemOperand(top_address)); |
| 3202 | 3143 |
| 3203 if (emit_debug_code()) { | 3144 if (emit_debug_code()) { |
| 3204 Tst(result_end, kObjectAlignmentMask); | 3145 Tst(result_end, kObjectAlignmentMask); |
| 3205 Check(eq, kUnalignedAllocationInNewSpace); | 3146 Check(eq, kUnalignedAllocationInNewSpace); |
| 3206 } | 3147 } |
| 3207 | 3148 |
| 3208 ObjectTag(result, result); | 3149 ObjectTag(result, result); |
| 3209 } | 3150 } |
| 3210 | 3151 |
| 3211 void MacroAssembler::AllocateTwoByteString(Register result, | |
| 3212 Register length, | |
| 3213 Register scratch1, | |
| 3214 Register scratch2, | |
| 3215 Register scratch3, | |
| 3216 Label* gc_required) { | |
| 3217 DCHECK(!AreAliased(result, length, scratch1, scratch2, scratch3)); | |
| 3218 // Calculate the number of bytes needed for the characters in the string while | |
| 3219 // observing object alignment. | |
| 3220 STATIC_ASSERT((SeqTwoByteString::kHeaderSize & kObjectAlignmentMask) == 0); | |
| 3221 Add(scratch1, length, length); // Length in bytes, not chars. | |
| 3222 Add(scratch1, scratch1, kObjectAlignmentMask + SeqTwoByteString::kHeaderSize); | |
| 3223 Bic(scratch1, scratch1, kObjectAlignmentMask); | |
| 3224 | |
| 3225 // Allocate two-byte string in new space. | |
| 3226 Allocate(scratch1, result, scratch2, scratch3, gc_required, | |
| 3227 NO_ALLOCATION_FLAGS); | |
| 3228 | |
| 3229 // Set the map, length and hash field. | |
| 3230 InitializeNewString(result, | |
| 3231 length, | |
| 3232 Heap::kStringMapRootIndex, | |
| 3233 scratch1, | |
| 3234 scratch2); | |
| 3235 } | |
| 3236 | |
| 3237 | |
| 3238 void MacroAssembler::AllocateOneByteString(Register result, Register length, | |
| 3239 Register scratch1, Register scratch2, | |
| 3240 Register scratch3, | |
| 3241 Label* gc_required) { | |
| 3242 DCHECK(!AreAliased(result, length, scratch1, scratch2, scratch3)); | |
| 3243 // Calculate the number of bytes needed for the characters in the string while | |
| 3244 // observing object alignment. | |
| 3245 STATIC_ASSERT((SeqOneByteString::kHeaderSize & kObjectAlignmentMask) == 0); | |
| 3246 STATIC_ASSERT(kCharSize == 1); | |
| 3247 Add(scratch1, length, kObjectAlignmentMask + SeqOneByteString::kHeaderSize); | |
| 3248 Bic(scratch1, scratch1, kObjectAlignmentMask); | |
| 3249 | |
| 3250 // Allocate one-byte string in new space. | |
| 3251 Allocate(scratch1, result, scratch2, scratch3, gc_required, | |
| 3252 NO_ALLOCATION_FLAGS); | |
| 3253 | |
| 3254 // Set the map, length and hash field. | |
| 3255 InitializeNewString(result, length, Heap::kOneByteStringMapRootIndex, | |
| 3256 scratch1, scratch2); | |
| 3257 } | |
| 3258 | |
| 3259 | |
| 3260 void MacroAssembler::AllocateTwoByteConsString(Register result, | |
| 3261 Register length, | |
| 3262 Register scratch1, | |
| 3263 Register scratch2, | |
| 3264 Label* gc_required) { | |
| 3265 Allocate(ConsString::kSize, result, scratch1, scratch2, gc_required, | |
| 3266 NO_ALLOCATION_FLAGS); | |
| 3267 | |
| 3268 InitializeNewString(result, | |
| 3269 length, | |
| 3270 Heap::kConsStringMapRootIndex, | |
| 3271 scratch1, | |
| 3272 scratch2); | |
| 3273 } | |
| 3274 | |
| 3275 | |
| 3276 void MacroAssembler::AllocateOneByteConsString(Register result, Register length, | |
| 3277 Register scratch1, | |
| 3278 Register scratch2, | |
| 3279 Label* gc_required) { | |
| 3280 Allocate(ConsString::kSize, result, scratch1, scratch2, gc_required, | |
| 3281 NO_ALLOCATION_FLAGS); | |
| 3282 | |
| 3283 InitializeNewString(result, length, Heap::kConsOneByteStringMapRootIndex, | |
| 3284 scratch1, scratch2); | |
| 3285 } | |
| 3286 | |
| 3287 | |
| 3288 void MacroAssembler::AllocateTwoByteSlicedString(Register result, | |
| 3289 Register length, | |
| 3290 Register scratch1, | |
| 3291 Register scratch2, | |
| 3292 Label* gc_required) { | |
| 3293 DCHECK(!AreAliased(result, length, scratch1, scratch2)); | |
| 3294 Allocate(SlicedString::kSize, result, scratch1, scratch2, gc_required, | |
| 3295 NO_ALLOCATION_FLAGS); | |
| 3296 | |
| 3297 InitializeNewString(result, | |
| 3298 length, | |
| 3299 Heap::kSlicedStringMapRootIndex, | |
| 3300 scratch1, | |
| 3301 scratch2); | |
| 3302 } | |
| 3303 | |
| 3304 | |
| 3305 void MacroAssembler::AllocateOneByteSlicedString(Register result, | |
| 3306 Register length, | |
| 3307 Register scratch1, | |
| 3308 Register scratch2, | |
| 3309 Label* gc_required) { | |
| 3310 DCHECK(!AreAliased(result, length, scratch1, scratch2)); | |
| 3311 Allocate(SlicedString::kSize, result, scratch1, scratch2, gc_required, | |
| 3312 NO_ALLOCATION_FLAGS); | |
| 3313 | |
| 3314 InitializeNewString(result, length, Heap::kSlicedOneByteStringMapRootIndex, | |
| 3315 scratch1, scratch2); | |
| 3316 } | |
| 3317 | |
| 3318 | |
| 3319 // Allocates a heap number or jumps to the need_gc label if the young space | 3152 // Allocates a heap number or jumps to the need_gc label if the young space |
| 3320 // is full and a scavenge is needed. | 3153 // is full and a scavenge is needed. |
| 3321 void MacroAssembler::AllocateHeapNumber(Register result, | 3154 void MacroAssembler::AllocateHeapNumber(Register result, |
| 3322 Label* gc_required, | 3155 Label* gc_required, |
| 3323 Register scratch1, | 3156 Register scratch1, |
| 3324 Register scratch2, | 3157 Register scratch2, |
| 3325 CPURegister value, | 3158 CPURegister value, |
| 3326 CPURegister heap_number_map, | 3159 CPURegister heap_number_map, |
| 3327 MutableMode mode) { | 3160 MutableMode mode) { |
| 3328 DCHECK(!value.IsValid() || value.Is64Bits()); | 3161 DCHECK(!value.IsValid() || value.Is64Bits()); |
| (...skipping 1495 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4824 } | 4657 } |
| 4825 | 4658 |
| 4826 | 4659 |
| 4827 #undef __ | 4660 #undef __ |
| 4828 | 4661 |
| 4829 | 4662 |
| 4830 } // namespace internal | 4663 } // namespace internal |
| 4831 } // namespace v8 | 4664 } // namespace v8 |
| 4832 | 4665 |
| 4833 #endif // V8_TARGET_ARCH_ARM64 | 4666 #endif // V8_TARGET_ARCH_ARM64 |
| OLD | NEW |