Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(48)

Side by Side Diff: src/arm64/macro-assembler-arm64.cc

Issue 1468073004: Reshuffle registers in JSConstructStub to avoid trashing costructor and new.target on fast path (so… (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 5 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/arm64/builtins-arm64.cc ('k') | src/ia32/builtins-ia32.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 3055 matching lines...) Expand 10 before | Expand all | Expand 10 after
3066 // Check relative positions of allocation top and limit addresses. 3066 // Check relative positions of allocation top and limit addresses.
3067 // The values must be adjacent in memory to allow the use of LDP. 3067 // The values must be adjacent in memory to allow the use of LDP.
3068 ExternalReference heap_allocation_top = 3068 ExternalReference heap_allocation_top =
3069 AllocationUtils::GetAllocationTopReference(isolate(), flags); 3069 AllocationUtils::GetAllocationTopReference(isolate(), flags);
3070 ExternalReference heap_allocation_limit = 3070 ExternalReference heap_allocation_limit =
3071 AllocationUtils::GetAllocationLimitReference(isolate(), flags); 3071 AllocationUtils::GetAllocationLimitReference(isolate(), flags);
3072 intptr_t top = reinterpret_cast<intptr_t>(heap_allocation_top.address()); 3072 intptr_t top = reinterpret_cast<intptr_t>(heap_allocation_top.address());
3073 intptr_t limit = reinterpret_cast<intptr_t>(heap_allocation_limit.address()); 3073 intptr_t limit = reinterpret_cast<intptr_t>(heap_allocation_limit.address());
3074 DCHECK((limit - top) == kPointerSize); 3074 DCHECK((limit - top) == kPointerSize);
3075 3075
3076 // Set up allocation top address and object size registers. 3076 // Set up allocation top address and allocation limit registers.
3077 Register top_address = scratch1; 3077 Register top_address = scratch1;
3078 Register allocation_limit = scratch2; 3078 Register alloc_limit = scratch2;
3079 Register result_end = scratch3;
3079 Mov(top_address, Operand(heap_allocation_top)); 3080 Mov(top_address, Operand(heap_allocation_top));
3080 3081
3081 if ((flags & RESULT_CONTAINS_TOP) == 0) { 3082 if ((flags & RESULT_CONTAINS_TOP) == 0) {
3082 // Load allocation top into result and the allocation limit. 3083 // Load allocation top into result and allocation limit into alloc_limit.
3083 Ldp(result, allocation_limit, MemOperand(top_address)); 3084 Ldp(result, alloc_limit, MemOperand(top_address));
3084 } else { 3085 } else {
3085 if (emit_debug_code()) { 3086 if (emit_debug_code()) {
3086 // Assert that result actually contains top on entry. 3087 // Assert that result actually contains top on entry.
3087 Ldr(scratch3, MemOperand(top_address)); 3088 Ldr(alloc_limit, MemOperand(top_address));
3088 Cmp(result, scratch3); 3089 Cmp(result, alloc_limit);
3089 Check(eq, kUnexpectedAllocationTop); 3090 Check(eq, kUnexpectedAllocationTop);
3090 } 3091 }
3091 // Load the allocation limit. 'result' already contains the allocation top. 3092 // Load allocation limit. Result already contains allocation top.
3092 Ldr(allocation_limit, MemOperand(top_address, limit - top)); 3093 Ldr(alloc_limit, MemOperand(top_address, limit - top));
3093 } 3094 }
3094 3095
3095 // We can ignore DOUBLE_ALIGNMENT flags here because doubles and pointers have 3096 // We can ignore DOUBLE_ALIGNMENT flags here because doubles and pointers have
3096 // the same alignment on ARM64. 3097 // the same alignment on ARM64.
3097 STATIC_ASSERT(kPointerAlignment == kDoubleAlignment); 3098 STATIC_ASSERT(kPointerAlignment == kDoubleAlignment);
3098 3099
3099 // Calculate new top and bail out if new space is exhausted. 3100 // Calculate new top and bail out if new space is exhausted.
3100 Adds(scratch3, result, object_size); 3101 Adds(result_end, result, object_size);
3101 Ccmp(scratch3, allocation_limit, CFlag, cc); 3102 Ccmp(result_end, alloc_limit, CFlag, cc);
3102 B(hi, gc_required); 3103 B(hi, gc_required);
3103 Str(scratch3, MemOperand(top_address)); 3104 Str(result_end, MemOperand(top_address));
3104 3105
3105 // Tag the object if requested. 3106 // Tag the object if requested.
3106 if ((flags & TAG_OBJECT) != 0) { 3107 if ((flags & TAG_OBJECT) != 0) {
3107 ObjectTag(result, result); 3108 ObjectTag(result, result);
3108 } 3109 }
3109 } 3110 }
3110 3111
3111 3112
3112 void MacroAssembler::Allocate(Register object_size, Register result, 3113 void MacroAssembler::Allocate(Register object_size, Register result,
3113 Register result_end, Register scratch, 3114 Register result_end, Register scratch,
3114 Label* gc_required, AllocationFlags flags) { 3115 Label* gc_required, AllocationFlags flags) {
3115 if (!FLAG_inline_new) { 3116 if (!FLAG_inline_new) {
3116 if (emit_debug_code()) { 3117 if (emit_debug_code()) {
3117 // Trash the registers to simulate an allocation failure. 3118 // Trash the registers to simulate an allocation failure.
3118 // We apply salt to the original zap value to easily spot the values. 3119 // We apply salt to the original zap value to easily spot the values.
3119 Mov(result, (kDebugZapValue & ~0xffL) | 0x11L); 3120 Mov(result, (kDebugZapValue & ~0xffL) | 0x11L);
3120 Mov(scratch, (kDebugZapValue & ~0xffL) | 0x21L); 3121 Mov(scratch, (kDebugZapValue & ~0xffL) | 0x21L);
3121 Mov(result_end, (kDebugZapValue & ~0xffL) | 0x21L); 3122 Mov(result_end, (kDebugZapValue & ~0xffL) | 0x21L);
3122 } 3123 }
3123 B(gc_required); 3124 B(gc_required);
3124 return; 3125 return;
3125 } 3126 }
3126 3127
3127 UseScratchRegisterScope temps(this); 3128 UseScratchRegisterScope temps(this);
3128 Register scratch2 = temps.AcquireX(); 3129 Register scratch2 = temps.AcquireX();
3129 3130
3130 DCHECK(!AreAliased(object_size, result, scratch, scratch2, result_end)); 3131 // |object_size| and |result_end| may overlap, other registers must not.
3132 DCHECK(!AreAliased(object_size, result, scratch, scratch2));
3133 DCHECK(!AreAliased(result_end, result, scratch, scratch2));
3131 DCHECK(object_size.Is64Bits() && result.Is64Bits() && scratch.Is64Bits() && 3134 DCHECK(object_size.Is64Bits() && result.Is64Bits() && scratch.Is64Bits() &&
3132 result_end.Is64Bits()); 3135 result_end.Is64Bits());
3133 3136
3134 // Check relative positions of allocation top and limit addresses. 3137 // Check relative positions of allocation top and limit addresses.
3135 // The values must be adjacent in memory to allow the use of LDP. 3138 // The values must be adjacent in memory to allow the use of LDP.
3136 ExternalReference heap_allocation_top = 3139 ExternalReference heap_allocation_top =
3137 AllocationUtils::GetAllocationTopReference(isolate(), flags); 3140 AllocationUtils::GetAllocationTopReference(isolate(), flags);
3138 ExternalReference heap_allocation_limit = 3141 ExternalReference heap_allocation_limit =
3139 AllocationUtils::GetAllocationLimitReference(isolate(), flags); 3142 AllocationUtils::GetAllocationLimitReference(isolate(), flags);
3140 intptr_t top = reinterpret_cast<intptr_t>(heap_allocation_top.address()); 3143 intptr_t top = reinterpret_cast<intptr_t>(heap_allocation_top.address());
3141 intptr_t limit = reinterpret_cast<intptr_t>(heap_allocation_limit.address()); 3144 intptr_t limit = reinterpret_cast<intptr_t>(heap_allocation_limit.address());
3142 DCHECK((limit - top) == kPointerSize); 3145 DCHECK((limit - top) == kPointerSize);
3143 3146
3144 // Set up allocation top address and object size registers. 3147 // Set up allocation top address and allocation limit registers.
3145 Register top_address = scratch; 3148 Register top_address = scratch;
3146 Register allocation_limit = scratch2; 3149 Register alloc_limit = scratch2;
3147 Mov(top_address, heap_allocation_top); 3150 Mov(top_address, heap_allocation_top);
3148 3151
3149 if ((flags & RESULT_CONTAINS_TOP) == 0) { 3152 if ((flags & RESULT_CONTAINS_TOP) == 0) {
3150 // Load allocation top into result and the allocation limit. 3153 // Load allocation top into result and allocation limit into alloc_limit.
3151 Ldp(result, allocation_limit, MemOperand(top_address)); 3154 Ldp(result, alloc_limit, MemOperand(top_address));
3152 } else { 3155 } else {
3153 if (emit_debug_code()) { 3156 if (emit_debug_code()) {
3154 // Assert that result actually contains top on entry. 3157 // Assert that result actually contains top on entry.
3155 Ldr(result_end, MemOperand(top_address)); 3158 Ldr(alloc_limit, MemOperand(top_address));
3156 Cmp(result, result_end); 3159 Cmp(result, alloc_limit);
3157 Check(eq, kUnexpectedAllocationTop); 3160 Check(eq, kUnexpectedAllocationTop);
3158 } 3161 }
3159 // Load the allocation limit. 'result' already contains the allocation top. 3162 // Load allocation limit. Result already contains allocation top.
3160 Ldr(allocation_limit, MemOperand(top_address, limit - top)); 3163 Ldr(alloc_limit, MemOperand(top_address, limit - top));
3161 } 3164 }
3162 3165
3163 // We can ignore DOUBLE_ALIGNMENT flags here because doubles and pointers have 3166 // We can ignore DOUBLE_ALIGNMENT flags here because doubles and pointers have
3164 // the same alignment on ARM64. 3167 // the same alignment on ARM64.
3165 STATIC_ASSERT(kPointerAlignment == kDoubleAlignment); 3168 STATIC_ASSERT(kPointerAlignment == kDoubleAlignment);
3166 3169
3167 // Calculate new top and bail out if new space is exhausted 3170 // Calculate new top and bail out if new space is exhausted
3168 if ((flags & SIZE_IN_WORDS) != 0) { 3171 if ((flags & SIZE_IN_WORDS) != 0) {
3169 Adds(result_end, result, Operand(object_size, LSL, kPointerSizeLog2)); 3172 Adds(result_end, result, Operand(object_size, LSL, kPointerSizeLog2));
3170 } else { 3173 } else {
3171 Adds(result_end, result, object_size); 3174 Adds(result_end, result, object_size);
3172 } 3175 }
3173 3176
3174 if (emit_debug_code()) { 3177 if (emit_debug_code()) {
3175 Tst(result_end, kObjectAlignmentMask); 3178 Tst(result_end, kObjectAlignmentMask);
3176 Check(eq, kUnalignedAllocationInNewSpace); 3179 Check(eq, kUnalignedAllocationInNewSpace);
3177 } 3180 }
3178 3181
3179 Ccmp(result_end, allocation_limit, CFlag, cc); 3182 Ccmp(result_end, alloc_limit, CFlag, cc);
3180 B(hi, gc_required); 3183 B(hi, gc_required);
3181 Str(result_end, MemOperand(top_address)); 3184 Str(result_end, MemOperand(top_address));
3182 3185
3183 // Tag the object if requested. 3186 // Tag the object if requested.
3184 if ((flags & TAG_OBJECT) != 0) { 3187 if ((flags & TAG_OBJECT) != 0) {
3185 ObjectTag(result, result); 3188 ObjectTag(result, result);
3186 } 3189 }
3187 } 3190 }
3188 3191
3189 3192
(...skipping 1873 matching lines...) Expand 10 before | Expand all | Expand 10 after
5063 } 5066 }
5064 5067
5065 5068
5066 #undef __ 5069 #undef __
5067 5070
5068 5071
5069 } // namespace internal 5072 } // namespace internal
5070 } // namespace v8 5073 } // namespace v8
5071 5074
5072 #endif // V8_TARGET_ARCH_ARM64 5075 #endif // V8_TARGET_ARCH_ARM64
OLDNEW
« no previous file with comments | « src/arm64/builtins-arm64.cc ('k') | src/ia32/builtins-ia32.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698