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 |