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 |