| 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 3012 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3023 } | 3023 } |
| 3024 | 3024 |
| 3025 | 3025 |
| 3026 void MacroAssembler::Allocate(int object_size, | 3026 void MacroAssembler::Allocate(int object_size, |
| 3027 Register result, | 3027 Register result, |
| 3028 Register scratch1, | 3028 Register scratch1, |
| 3029 Register scratch2, | 3029 Register scratch2, |
| 3030 Label* gc_required, | 3030 Label* gc_required, |
| 3031 AllocationFlags flags) { | 3031 AllocationFlags flags) { |
| 3032 DCHECK(object_size <= Page::kMaxRegularHeapObjectSize); | 3032 DCHECK(object_size <= Page::kMaxRegularHeapObjectSize); |
| 3033 DCHECK((flags & ALLOCATION_FOLDED) == 0); |
| 3033 if (!FLAG_inline_new) { | 3034 if (!FLAG_inline_new) { |
| 3034 if (emit_debug_code()) { | 3035 if (emit_debug_code()) { |
| 3035 // Trash the registers to simulate an allocation failure. | 3036 // Trash the registers to simulate an allocation failure. |
| 3036 // We apply salt to the original zap value to easily spot the values. | 3037 // We apply salt to the original zap value to easily spot the values. |
| 3037 Mov(result, (kDebugZapValue & ~0xffL) | 0x11L); | 3038 Mov(result, (kDebugZapValue & ~0xffL) | 0x11L); |
| 3038 Mov(scratch1, (kDebugZapValue & ~0xffL) | 0x21L); | 3039 Mov(scratch1, (kDebugZapValue & ~0xffL) | 0x21L); |
| 3039 Mov(scratch2, (kDebugZapValue & ~0xffL) | 0x21L); | 3040 Mov(scratch2, (kDebugZapValue & ~0xffL) | 0x21L); |
| 3040 } | 3041 } |
| 3041 B(gc_required); | 3042 B(gc_required); |
| 3042 return; | 3043 return; |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3085 } | 3086 } |
| 3086 | 3087 |
| 3087 // We can ignore DOUBLE_ALIGNMENT flags here because doubles and pointers have | 3088 // We can ignore DOUBLE_ALIGNMENT flags here because doubles and pointers have |
| 3088 // the same alignment on ARM64. | 3089 // the same alignment on ARM64. |
| 3089 STATIC_ASSERT(kPointerAlignment == kDoubleAlignment); | 3090 STATIC_ASSERT(kPointerAlignment == kDoubleAlignment); |
| 3090 | 3091 |
| 3091 // Calculate new top and bail out if new space is exhausted. | 3092 // Calculate new top and bail out if new space is exhausted. |
| 3092 Adds(result_end, result, object_size); | 3093 Adds(result_end, result, object_size); |
| 3093 Ccmp(result_end, alloc_limit, NoFlag, cc); | 3094 Ccmp(result_end, alloc_limit, NoFlag, cc); |
| 3094 B(hi, gc_required); | 3095 B(hi, gc_required); |
| 3095 Str(result_end, MemOperand(top_address)); | 3096 |
| 3097 if ((flags & ALLOCATION_FOLDING_DOMINATOR) == 0) { |
| 3098 // The top pointer is not updated for allocation folding dominators. |
| 3099 Str(result_end, MemOperand(top_address)); |
| 3100 } |
| 3096 | 3101 |
| 3097 // Tag the object. | 3102 // Tag the object. |
| 3098 ObjectTag(result, result); | 3103 ObjectTag(result, result); |
| 3099 } | 3104 } |
| 3100 | 3105 |
| 3101 | 3106 |
| 3102 void MacroAssembler::Allocate(Register object_size, Register result, | 3107 void MacroAssembler::Allocate(Register object_size, Register result, |
| 3103 Register result_end, Register scratch, | 3108 Register result_end, Register scratch, |
| 3104 Label* gc_required, AllocationFlags flags) { | 3109 Label* gc_required, AllocationFlags flags) { |
| 3105 if (!FLAG_inline_new) { | 3110 if (!FLAG_inline_new) { |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3161 Adds(result_end, result, Operand(object_size, LSL, kPointerSizeLog2)); | 3166 Adds(result_end, result, Operand(object_size, LSL, kPointerSizeLog2)); |
| 3162 } else { | 3167 } else { |
| 3163 Adds(result_end, result, object_size); | 3168 Adds(result_end, result, object_size); |
| 3164 } | 3169 } |
| 3165 | 3170 |
| 3166 if (emit_debug_code()) { | 3171 if (emit_debug_code()) { |
| 3167 Tst(result_end, kObjectAlignmentMask); | 3172 Tst(result_end, kObjectAlignmentMask); |
| 3168 Check(eq, kUnalignedAllocationInNewSpace); | 3173 Check(eq, kUnalignedAllocationInNewSpace); |
| 3169 } | 3174 } |
| 3170 | 3175 |
| 3171 Ccmp(result_end, alloc_limit, CFlag, cc); | 3176 Ccmp(result_end, alloc_limit, NoFlag, cc); |
| 3172 B(hi, gc_required); | 3177 B(hi, gc_required); |
| 3173 Str(result_end, MemOperand(top_address)); | 3178 |
| 3179 if ((flags & ALLOCATION_FOLDING_DOMINATOR) == 0) { |
| 3180 // The top pointer is not updated for allocation folding dominators. |
| 3181 Str(result_end, MemOperand(top_address)); |
| 3182 } |
| 3174 | 3183 |
| 3175 // Tag the object. | 3184 // Tag the object. |
| 3176 ObjectTag(result, result); | 3185 ObjectTag(result, result); |
| 3177 } | 3186 } |
| 3178 | 3187 |
| 3188 void MacroAssembler::FastAllocate(int object_size, Register result, |
| 3189 Register scratch1, Register scratch2, |
| 3190 AllocationFlags flags) { |
| 3191 DCHECK(object_size <= Page::kMaxRegularHeapObjectSize); |
| 3192 |
| 3193 DCHECK(!AreAliased(result, scratch1, scratch2)); |
| 3194 DCHECK(result.Is64Bits() && scratch1.Is64Bits() && scratch2.Is64Bits()); |
| 3195 |
| 3196 // Make object size into bytes. |
| 3197 if ((flags & SIZE_IN_WORDS) != 0) { |
| 3198 object_size *= kPointerSize; |
| 3199 } |
| 3200 DCHECK(0 == (object_size & kObjectAlignmentMask)); |
| 3201 |
| 3202 ExternalReference heap_allocation_top = |
| 3203 AllocationUtils::GetAllocationTopReference(isolate(), flags); |
| 3204 |
| 3205 // Set up allocation top address and allocation limit registers. |
| 3206 Register top_address = scratch1; |
| 3207 Register result_end = scratch2; |
| 3208 Mov(top_address, Operand(heap_allocation_top)); |
| 3209 Ldr(result, MemOperand(top_address)); |
| 3210 |
| 3211 // We can ignore DOUBLE_ALIGNMENT flags here because doubles and pointers have |
| 3212 // the same alignment on ARM64. |
| 3213 STATIC_ASSERT(kPointerAlignment == kDoubleAlignment); |
| 3214 |
| 3215 // Calculate new top and write it back. |
| 3216 Adds(result_end, result, object_size); |
| 3217 Str(result_end, MemOperand(top_address)); |
| 3218 |
| 3219 ObjectTag(result, result); |
| 3220 } |
| 3221 |
| 3222 void MacroAssembler::FastAllocate(Register object_size, Register result, |
| 3223 Register result_end, Register scratch, |
| 3224 AllocationFlags flags) { |
| 3225 // |object_size| and |result_end| may overlap, other registers must not. |
| 3226 DCHECK(!AreAliased(object_size, result, scratch)); |
| 3227 DCHECK(!AreAliased(result_end, result, scratch)); |
| 3228 DCHECK(object_size.Is64Bits() && result.Is64Bits() && scratch.Is64Bits() && |
| 3229 result_end.Is64Bits()); |
| 3230 |
| 3231 ExternalReference heap_allocation_top = |
| 3232 AllocationUtils::GetAllocationTopReference(isolate(), flags); |
| 3233 |
| 3234 // Set up allocation top address and allocation limit registers. |
| 3235 Register top_address = scratch; |
| 3236 Mov(top_address, heap_allocation_top); |
| 3237 Ldr(result, MemOperand(top_address)); |
| 3238 |
| 3239 // We can ignore DOUBLE_ALIGNMENT flags here because doubles and pointers have |
| 3240 // the same alignment on ARM64. |
| 3241 STATIC_ASSERT(kPointerAlignment == kDoubleAlignment); |
| 3242 |
| 3243 // Calculate new top and write it back. |
| 3244 if ((flags & SIZE_IN_WORDS) != 0) { |
| 3245 Adds(result_end, result, Operand(object_size, LSL, kPointerSizeLog2)); |
| 3246 } else { |
| 3247 Adds(result_end, result, object_size); |
| 3248 } |
| 3249 Str(result_end, MemOperand(top_address)); |
| 3250 |
| 3251 if (emit_debug_code()) { |
| 3252 Tst(result_end, kObjectAlignmentMask); |
| 3253 Check(eq, kUnalignedAllocationInNewSpace); |
| 3254 } |
| 3255 |
| 3256 ObjectTag(result, result); |
| 3257 } |
| 3179 | 3258 |
| 3180 void MacroAssembler::AllocateTwoByteString(Register result, | 3259 void MacroAssembler::AllocateTwoByteString(Register result, |
| 3181 Register length, | 3260 Register length, |
| 3182 Register scratch1, | 3261 Register scratch1, |
| 3183 Register scratch2, | 3262 Register scratch2, |
| 3184 Register scratch3, | 3263 Register scratch3, |
| 3185 Label* gc_required) { | 3264 Label* gc_required) { |
| 3186 DCHECK(!AreAliased(result, length, scratch1, scratch2, scratch3)); | 3265 DCHECK(!AreAliased(result, length, scratch1, scratch2, scratch3)); |
| 3187 // Calculate the number of bytes needed for the characters in the string while | 3266 // Calculate the number of bytes needed for the characters in the string while |
| 3188 // observing object alignment. | 3267 // observing object alignment. |
| (...skipping 1877 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5066 } | 5145 } |
| 5067 | 5146 |
| 5068 | 5147 |
| 5069 #undef __ | 5148 #undef __ |
| 5070 | 5149 |
| 5071 | 5150 |
| 5072 } // namespace internal | 5151 } // namespace internal |
| 5073 } // namespace v8 | 5152 } // namespace v8 |
| 5074 | 5153 |
| 5075 #endif // V8_TARGET_ARCH_ARM64 | 5154 #endif // V8_TARGET_ARCH_ARM64 |
| OLD | NEW |