| 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 3076 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3087 // We can ignore DOUBLE_ALIGNMENT flags here because doubles and pointers have | 3087 // We can ignore DOUBLE_ALIGNMENT flags here because doubles and pointers have |
| 3088 // the same alignment on ARM64. | 3088 // the same alignment on ARM64. |
| 3089 STATIC_ASSERT(kPointerAlignment == kDoubleAlignment); | 3089 STATIC_ASSERT(kPointerAlignment == kDoubleAlignment); |
| 3090 | 3090 |
| 3091 // Calculate new top and bail out if new space is exhausted. | 3091 // Calculate new top and bail out if new space is exhausted. |
| 3092 Adds(result_end, result, object_size); | 3092 Adds(result_end, result, object_size); |
| 3093 Ccmp(result_end, alloc_limit, NoFlag, cc); | 3093 Ccmp(result_end, alloc_limit, NoFlag, cc); |
| 3094 B(hi, gc_required); | 3094 B(hi, gc_required); |
| 3095 Str(result_end, MemOperand(top_address)); | 3095 Str(result_end, MemOperand(top_address)); |
| 3096 | 3096 |
| 3097 // Tag the object if requested. | 3097 // Tag the object. |
| 3098 if ((flags & TAG_OBJECT) != 0) { | 3098 ObjectTag(result, result); |
| 3099 ObjectTag(result, result); | |
| 3100 } | |
| 3101 } | 3099 } |
| 3102 | 3100 |
| 3103 | 3101 |
| 3104 void MacroAssembler::Allocate(Register object_size, Register result, | 3102 void MacroAssembler::Allocate(Register object_size, Register result, |
| 3105 Register result_end, Register scratch, | 3103 Register result_end, Register scratch, |
| 3106 Label* gc_required, AllocationFlags flags) { | 3104 Label* gc_required, AllocationFlags flags) { |
| 3107 if (!FLAG_inline_new) { | 3105 if (!FLAG_inline_new) { |
| 3108 if (emit_debug_code()) { | 3106 if (emit_debug_code()) { |
| 3109 // Trash the registers to simulate an allocation failure. | 3107 // Trash the registers to simulate an allocation failure. |
| 3110 // We apply salt to the original zap value to easily spot the values. | 3108 // We apply salt to the original zap value to easily spot the values. |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3167 | 3165 |
| 3168 if (emit_debug_code()) { | 3166 if (emit_debug_code()) { |
| 3169 Tst(result_end, kObjectAlignmentMask); | 3167 Tst(result_end, kObjectAlignmentMask); |
| 3170 Check(eq, kUnalignedAllocationInNewSpace); | 3168 Check(eq, kUnalignedAllocationInNewSpace); |
| 3171 } | 3169 } |
| 3172 | 3170 |
| 3173 Ccmp(result_end, alloc_limit, CFlag, cc); | 3171 Ccmp(result_end, alloc_limit, CFlag, cc); |
| 3174 B(hi, gc_required); | 3172 B(hi, gc_required); |
| 3175 Str(result_end, MemOperand(top_address)); | 3173 Str(result_end, MemOperand(top_address)); |
| 3176 | 3174 |
| 3177 // Tag the object if requested. | 3175 // Tag the object. |
| 3178 if ((flags & TAG_OBJECT) != 0) { | 3176 ObjectTag(result, result); |
| 3179 ObjectTag(result, result); | |
| 3180 } | |
| 3181 } | 3177 } |
| 3182 | 3178 |
| 3183 | 3179 |
| 3184 void MacroAssembler::AllocateTwoByteString(Register result, | 3180 void MacroAssembler::AllocateTwoByteString(Register result, |
| 3185 Register length, | 3181 Register length, |
| 3186 Register scratch1, | 3182 Register scratch1, |
| 3187 Register scratch2, | 3183 Register scratch2, |
| 3188 Register scratch3, | 3184 Register scratch3, |
| 3189 Label* gc_required) { | 3185 Label* gc_required) { |
| 3190 DCHECK(!AreAliased(result, length, scratch1, scratch2, scratch3)); | 3186 DCHECK(!AreAliased(result, length, scratch1, scratch2, scratch3)); |
| 3191 // Calculate the number of bytes needed for the characters in the string while | 3187 // Calculate the number of bytes needed for the characters in the string while |
| 3192 // observing object alignment. | 3188 // observing object alignment. |
| 3193 STATIC_ASSERT((SeqTwoByteString::kHeaderSize & kObjectAlignmentMask) == 0); | 3189 STATIC_ASSERT((SeqTwoByteString::kHeaderSize & kObjectAlignmentMask) == 0); |
| 3194 Add(scratch1, length, length); // Length in bytes, not chars. | 3190 Add(scratch1, length, length); // Length in bytes, not chars. |
| 3195 Add(scratch1, scratch1, kObjectAlignmentMask + SeqTwoByteString::kHeaderSize); | 3191 Add(scratch1, scratch1, kObjectAlignmentMask + SeqTwoByteString::kHeaderSize); |
| 3196 Bic(scratch1, scratch1, kObjectAlignmentMask); | 3192 Bic(scratch1, scratch1, kObjectAlignmentMask); |
| 3197 | 3193 |
| 3198 // Allocate two-byte string in new space. | 3194 // Allocate two-byte string in new space. |
| 3199 Allocate(scratch1, | 3195 Allocate(scratch1, result, scratch2, scratch3, gc_required, |
| 3200 result, | 3196 NO_ALLOCATION_FLAGS); |
| 3201 scratch2, | |
| 3202 scratch3, | |
| 3203 gc_required, | |
| 3204 TAG_OBJECT); | |
| 3205 | 3197 |
| 3206 // Set the map, length and hash field. | 3198 // Set the map, length and hash field. |
| 3207 InitializeNewString(result, | 3199 InitializeNewString(result, |
| 3208 length, | 3200 length, |
| 3209 Heap::kStringMapRootIndex, | 3201 Heap::kStringMapRootIndex, |
| 3210 scratch1, | 3202 scratch1, |
| 3211 scratch2); | 3203 scratch2); |
| 3212 } | 3204 } |
| 3213 | 3205 |
| 3214 | 3206 |
| 3215 void MacroAssembler::AllocateOneByteString(Register result, Register length, | 3207 void MacroAssembler::AllocateOneByteString(Register result, Register length, |
| 3216 Register scratch1, Register scratch2, | 3208 Register scratch1, Register scratch2, |
| 3217 Register scratch3, | 3209 Register scratch3, |
| 3218 Label* gc_required) { | 3210 Label* gc_required) { |
| 3219 DCHECK(!AreAliased(result, length, scratch1, scratch2, scratch3)); | 3211 DCHECK(!AreAliased(result, length, scratch1, scratch2, scratch3)); |
| 3220 // Calculate the number of bytes needed for the characters in the string while | 3212 // Calculate the number of bytes needed for the characters in the string while |
| 3221 // observing object alignment. | 3213 // observing object alignment. |
| 3222 STATIC_ASSERT((SeqOneByteString::kHeaderSize & kObjectAlignmentMask) == 0); | 3214 STATIC_ASSERT((SeqOneByteString::kHeaderSize & kObjectAlignmentMask) == 0); |
| 3223 STATIC_ASSERT(kCharSize == 1); | 3215 STATIC_ASSERT(kCharSize == 1); |
| 3224 Add(scratch1, length, kObjectAlignmentMask + SeqOneByteString::kHeaderSize); | 3216 Add(scratch1, length, kObjectAlignmentMask + SeqOneByteString::kHeaderSize); |
| 3225 Bic(scratch1, scratch1, kObjectAlignmentMask); | 3217 Bic(scratch1, scratch1, kObjectAlignmentMask); |
| 3226 | 3218 |
| 3227 // Allocate one-byte string in new space. | 3219 // Allocate one-byte string in new space. |
| 3228 Allocate(scratch1, | 3220 Allocate(scratch1, result, scratch2, scratch3, gc_required, |
| 3229 result, | 3221 NO_ALLOCATION_FLAGS); |
| 3230 scratch2, | |
| 3231 scratch3, | |
| 3232 gc_required, | |
| 3233 TAG_OBJECT); | |
| 3234 | 3222 |
| 3235 // Set the map, length and hash field. | 3223 // Set the map, length and hash field. |
| 3236 InitializeNewString(result, length, Heap::kOneByteStringMapRootIndex, | 3224 InitializeNewString(result, length, Heap::kOneByteStringMapRootIndex, |
| 3237 scratch1, scratch2); | 3225 scratch1, scratch2); |
| 3238 } | 3226 } |
| 3239 | 3227 |
| 3240 | 3228 |
| 3241 void MacroAssembler::AllocateTwoByteConsString(Register result, | 3229 void MacroAssembler::AllocateTwoByteConsString(Register result, |
| 3242 Register length, | 3230 Register length, |
| 3243 Register scratch1, | 3231 Register scratch1, |
| 3244 Register scratch2, | 3232 Register scratch2, |
| 3245 Label* gc_required) { | 3233 Label* gc_required) { |
| 3246 Allocate(ConsString::kSize, result, scratch1, scratch2, gc_required, | 3234 Allocate(ConsString::kSize, result, scratch1, scratch2, gc_required, |
| 3247 TAG_OBJECT); | 3235 NO_ALLOCATION_FLAGS); |
| 3248 | 3236 |
| 3249 InitializeNewString(result, | 3237 InitializeNewString(result, |
| 3250 length, | 3238 length, |
| 3251 Heap::kConsStringMapRootIndex, | 3239 Heap::kConsStringMapRootIndex, |
| 3252 scratch1, | 3240 scratch1, |
| 3253 scratch2); | 3241 scratch2); |
| 3254 } | 3242 } |
| 3255 | 3243 |
| 3256 | 3244 |
| 3257 void MacroAssembler::AllocateOneByteConsString(Register result, Register length, | 3245 void MacroAssembler::AllocateOneByteConsString(Register result, Register length, |
| 3258 Register scratch1, | 3246 Register scratch1, |
| 3259 Register scratch2, | 3247 Register scratch2, |
| 3260 Label* gc_required) { | 3248 Label* gc_required) { |
| 3261 Allocate(ConsString::kSize, | 3249 Allocate(ConsString::kSize, result, scratch1, scratch2, gc_required, |
| 3262 result, | 3250 NO_ALLOCATION_FLAGS); |
| 3263 scratch1, | |
| 3264 scratch2, | |
| 3265 gc_required, | |
| 3266 TAG_OBJECT); | |
| 3267 | 3251 |
| 3268 InitializeNewString(result, length, Heap::kConsOneByteStringMapRootIndex, | 3252 InitializeNewString(result, length, Heap::kConsOneByteStringMapRootIndex, |
| 3269 scratch1, scratch2); | 3253 scratch1, scratch2); |
| 3270 } | 3254 } |
| 3271 | 3255 |
| 3272 | 3256 |
| 3273 void MacroAssembler::AllocateTwoByteSlicedString(Register result, | 3257 void MacroAssembler::AllocateTwoByteSlicedString(Register result, |
| 3274 Register length, | 3258 Register length, |
| 3275 Register scratch1, | 3259 Register scratch1, |
| 3276 Register scratch2, | 3260 Register scratch2, |
| 3277 Label* gc_required) { | 3261 Label* gc_required) { |
| 3278 DCHECK(!AreAliased(result, length, scratch1, scratch2)); | 3262 DCHECK(!AreAliased(result, length, scratch1, scratch2)); |
| 3279 Allocate(SlicedString::kSize, result, scratch1, scratch2, gc_required, | 3263 Allocate(SlicedString::kSize, result, scratch1, scratch2, gc_required, |
| 3280 TAG_OBJECT); | 3264 NO_ALLOCATION_FLAGS); |
| 3281 | 3265 |
| 3282 InitializeNewString(result, | 3266 InitializeNewString(result, |
| 3283 length, | 3267 length, |
| 3284 Heap::kSlicedStringMapRootIndex, | 3268 Heap::kSlicedStringMapRootIndex, |
| 3285 scratch1, | 3269 scratch1, |
| 3286 scratch2); | 3270 scratch2); |
| 3287 } | 3271 } |
| 3288 | 3272 |
| 3289 | 3273 |
| 3290 void MacroAssembler::AllocateOneByteSlicedString(Register result, | 3274 void MacroAssembler::AllocateOneByteSlicedString(Register result, |
| 3291 Register length, | 3275 Register length, |
| 3292 Register scratch1, | 3276 Register scratch1, |
| 3293 Register scratch2, | 3277 Register scratch2, |
| 3294 Label* gc_required) { | 3278 Label* gc_required) { |
| 3295 DCHECK(!AreAliased(result, length, scratch1, scratch2)); | 3279 DCHECK(!AreAliased(result, length, scratch1, scratch2)); |
| 3296 Allocate(SlicedString::kSize, result, scratch1, scratch2, gc_required, | 3280 Allocate(SlicedString::kSize, result, scratch1, scratch2, gc_required, |
| 3297 TAG_OBJECT); | 3281 NO_ALLOCATION_FLAGS); |
| 3298 | 3282 |
| 3299 InitializeNewString(result, length, Heap::kSlicedOneByteStringMapRootIndex, | 3283 InitializeNewString(result, length, Heap::kSlicedOneByteStringMapRootIndex, |
| 3300 scratch1, scratch2); | 3284 scratch1, scratch2); |
| 3301 } | 3285 } |
| 3302 | 3286 |
| 3303 | 3287 |
| 3304 // Allocates a heap number or jumps to the need_gc label if the young space | 3288 // Allocates a heap number or jumps to the need_gc label if the young space |
| 3305 // is full and a scavenge is needed. | 3289 // is full and a scavenge is needed. |
| 3306 void MacroAssembler::AllocateHeapNumber(Register result, | 3290 void MacroAssembler::AllocateHeapNumber(Register result, |
| 3307 Label* gc_required, | 3291 Label* gc_required, |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3341 } else { | 3325 } else { |
| 3342 map = Register(heap_number_map); | 3326 map = Register(heap_number_map); |
| 3343 } | 3327 } |
| 3344 AssertRegisterIsRoot(map, map_index); | 3328 AssertRegisterIsRoot(map, map_index); |
| 3345 } | 3329 } |
| 3346 | 3330 |
| 3347 // Store the heap number map and the value in the allocated object. | 3331 // Store the heap number map and the value in the allocated object. |
| 3348 if (value.IsSameSizeAndType(heap_number_map)) { | 3332 if (value.IsSameSizeAndType(heap_number_map)) { |
| 3349 STATIC_ASSERT(HeapObject::kMapOffset + kPointerSize == | 3333 STATIC_ASSERT(HeapObject::kMapOffset + kPointerSize == |
| 3350 HeapNumber::kValueOffset); | 3334 HeapNumber::kValueOffset); |
| 3351 Stp(heap_number_map, value, MemOperand(result, HeapObject::kMapOffset)); | 3335 Stp(heap_number_map, value, |
| 3336 FieldMemOperand(result, HeapObject::kMapOffset)); |
| 3352 } else { | 3337 } else { |
| 3353 Str(heap_number_map, MemOperand(result, HeapObject::kMapOffset)); | 3338 Str(heap_number_map, FieldMemOperand(result, HeapObject::kMapOffset)); |
| 3354 if (value.IsValid()) { | 3339 if (value.IsValid()) { |
| 3355 Str(value, MemOperand(result, HeapNumber::kValueOffset)); | 3340 Str(value, FieldMemOperand(result, HeapNumber::kValueOffset)); |
| 3356 } | 3341 } |
| 3357 } | 3342 } |
| 3358 ObjectTag(result, result); | |
| 3359 } | 3343 } |
| 3360 | 3344 |
| 3361 | 3345 |
| 3362 void MacroAssembler::JumpIfObjectType(Register object, | 3346 void MacroAssembler::JumpIfObjectType(Register object, |
| 3363 Register map, | 3347 Register map, |
| 3364 Register type_reg, | 3348 Register type_reg, |
| 3365 InstanceType type, | 3349 InstanceType type, |
| 3366 Label* if_cond_pass, | 3350 Label* if_cond_pass, |
| 3367 Condition cond) { | 3351 Condition cond) { |
| 3368 CompareObjectType(object, map, type_reg, type); | 3352 CompareObjectType(object, map, type_reg, type); |
| 3369 B(cond, if_cond_pass); | 3353 B(cond, if_cond_pass); |
| 3370 } | 3354 } |
| 3371 | 3355 |
| 3372 | 3356 |
| 3373 void MacroAssembler::AllocateJSValue(Register result, Register constructor, | 3357 void MacroAssembler::AllocateJSValue(Register result, Register constructor, |
| 3374 Register value, Register scratch1, | 3358 Register value, Register scratch1, |
| 3375 Register scratch2, Label* gc_required) { | 3359 Register scratch2, Label* gc_required) { |
| 3376 DCHECK(!result.is(constructor)); | 3360 DCHECK(!result.is(constructor)); |
| 3377 DCHECK(!result.is(scratch1)); | 3361 DCHECK(!result.is(scratch1)); |
| 3378 DCHECK(!result.is(scratch2)); | 3362 DCHECK(!result.is(scratch2)); |
| 3379 DCHECK(!result.is(value)); | 3363 DCHECK(!result.is(value)); |
| 3380 | 3364 |
| 3381 // Allocate JSValue in new space. | 3365 // Allocate JSValue in new space. |
| 3382 Allocate(JSValue::kSize, result, scratch1, scratch2, gc_required, TAG_OBJECT); | 3366 Allocate(JSValue::kSize, result, scratch1, scratch2, gc_required, |
| 3367 NO_ALLOCATION_FLAGS); |
| 3383 | 3368 |
| 3384 // Initialize the JSValue. | 3369 // Initialize the JSValue. |
| 3385 LoadGlobalFunctionInitialMap(constructor, scratch1, scratch2); | 3370 LoadGlobalFunctionInitialMap(constructor, scratch1, scratch2); |
| 3386 Str(scratch1, FieldMemOperand(result, HeapObject::kMapOffset)); | 3371 Str(scratch1, FieldMemOperand(result, HeapObject::kMapOffset)); |
| 3387 LoadRoot(scratch1, Heap::kEmptyFixedArrayRootIndex); | 3372 LoadRoot(scratch1, Heap::kEmptyFixedArrayRootIndex); |
| 3388 Str(scratch1, FieldMemOperand(result, JSObject::kPropertiesOffset)); | 3373 Str(scratch1, FieldMemOperand(result, JSObject::kPropertiesOffset)); |
| 3389 Str(scratch1, FieldMemOperand(result, JSObject::kElementsOffset)); | 3374 Str(scratch1, FieldMemOperand(result, JSObject::kElementsOffset)); |
| 3390 Str(value, FieldMemOperand(result, JSValue::kValueOffset)); | 3375 Str(value, FieldMemOperand(result, JSValue::kValueOffset)); |
| 3391 STATIC_ASSERT(JSValue::kSize == 4 * kPointerSize); | 3376 STATIC_ASSERT(JSValue::kSize == 4 * kPointerSize); |
| 3392 } | 3377 } |
| (...skipping 1688 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5081 } | 5066 } |
| 5082 | 5067 |
| 5083 | 5068 |
| 5084 #undef __ | 5069 #undef __ |
| 5085 | 5070 |
| 5086 | 5071 |
| 5087 } // namespace internal | 5072 } // namespace internal |
| 5088 } // namespace v8 | 5073 } // namespace v8 |
| 5089 | 5074 |
| 5090 #endif // V8_TARGET_ARCH_ARM64 | 5075 #endif // V8_TARGET_ARCH_ARM64 |
| OLD | NEW |