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

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

Issue 1899813003: [crankshaft] Fragmentation-free allocation folding. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 4 years, 7 months 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/arm/macro-assembler-arm.h ('k') | src/arm64/macro-assembler-arm64.h » ('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 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 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 #include <limits.h> // For LONG_MIN, LONG_MAX. 5 #include <limits.h> // For LONG_MIN, LONG_MAX.
6 6
7 #if V8_TARGET_ARCH_ARM 7 #if V8_TARGET_ARCH_ARM
8 8
9 #include "src/base/bits.h" 9 #include "src/base/bits.h"
10 #include "src/base/division-by-constant.h" 10 #include "src/base/division-by-constant.h"
(...skipping 1967 matching lines...) Expand 10 before | Expand all | Expand 10 after
1978 } 1978 }
1979 1979
1980 1980
1981 void MacroAssembler::Allocate(int object_size, 1981 void MacroAssembler::Allocate(int object_size,
1982 Register result, 1982 Register result,
1983 Register scratch1, 1983 Register scratch1,
1984 Register scratch2, 1984 Register scratch2,
1985 Label* gc_required, 1985 Label* gc_required,
1986 AllocationFlags flags) { 1986 AllocationFlags flags) {
1987 DCHECK(object_size <= Page::kMaxRegularHeapObjectSize); 1987 DCHECK(object_size <= Page::kMaxRegularHeapObjectSize);
1988 DCHECK((flags & ALLOCATION_FOLDED) == 0);
1988 if (!FLAG_inline_new) { 1989 if (!FLAG_inline_new) {
1989 if (emit_debug_code()) { 1990 if (emit_debug_code()) {
1990 // Trash the registers to simulate an allocation failure. 1991 // Trash the registers to simulate an allocation failure.
1991 mov(result, Operand(0x7091)); 1992 mov(result, Operand(0x7091));
1992 mov(scratch1, Operand(0x7191)); 1993 mov(scratch1, Operand(0x7191));
1993 mov(scratch2, Operand(0x7291)); 1994 mov(scratch2, Operand(0x7291));
1994 } 1995 }
1995 jmp(gc_required); 1996 jmp(gc_required);
1996 return; 1997 return;
1997 } 1998 }
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
2070 int bits = object_size & (0xff << shift); 2071 int bits = object_size & (0xff << shift);
2071 object_size -= bits; 2072 object_size -= bits;
2072 shift += 8; 2073 shift += 8;
2073 Operand bits_operand(bits); 2074 Operand bits_operand(bits);
2074 DCHECK(bits_operand.instructions_required(this) == 1); 2075 DCHECK(bits_operand.instructions_required(this) == 1);
2075 add(result_end, source, bits_operand, LeaveCC, cond); 2076 add(result_end, source, bits_operand, LeaveCC, cond);
2076 source = result_end; 2077 source = result_end;
2077 cond = cc; 2078 cond = cc;
2078 } 2079 }
2079 } 2080 }
2081
2080 cmp(result_end, Operand(alloc_limit)); 2082 cmp(result_end, Operand(alloc_limit));
2081 b(hi, gc_required); 2083 b(hi, gc_required);
2082 str(result_end, MemOperand(top_address)); 2084
2085 if ((flags & ALLOCATION_FOLDING_DOMINATOR) == 0) {
2086 // The top pointer is not updated for allocation folding dominators.
2087 str(result_end, MemOperand(top_address));
2088 }
2083 2089
2084 // Tag object. 2090 // Tag object.
2085 add(result, result, Operand(kHeapObjectTag)); 2091 add(result, result, Operand(kHeapObjectTag));
2086 } 2092 }
2087 2093
2088 2094
2089 void MacroAssembler::Allocate(Register object_size, Register result, 2095 void MacroAssembler::Allocate(Register object_size, Register result,
2090 Register result_end, Register scratch, 2096 Register result_end, Register scratch,
2091 Label* gc_required, AllocationFlags flags) { 2097 Label* gc_required, AllocationFlags flags) {
2098 DCHECK((flags & ALLOCATION_FOLDED) == 0);
2092 if (!FLAG_inline_new) { 2099 if (!FLAG_inline_new) {
2093 if (emit_debug_code()) { 2100 if (emit_debug_code()) {
2094 // Trash the registers to simulate an allocation failure. 2101 // Trash the registers to simulate an allocation failure.
2095 mov(result, Operand(0x7091)); 2102 mov(result, Operand(0x7091));
2096 mov(scratch, Operand(0x7191)); 2103 mov(scratch, Operand(0x7191));
2097 mov(result_end, Operand(0x7291)); 2104 mov(result_end, Operand(0x7291));
2098 } 2105 }
2099 jmp(gc_required); 2106 jmp(gc_required);
2100 return; 2107 return;
2101 } 2108 }
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
2157 } 2164 }
2158 2165
2159 // Calculate new top and bail out if new space is exhausted. Use result 2166 // Calculate new top and bail out if new space is exhausted. Use result
2160 // to calculate the new top. Object size may be in words so a shift is 2167 // to calculate the new top. Object size may be in words so a shift is
2161 // required to get the number of bytes. 2168 // required to get the number of bytes.
2162 if ((flags & SIZE_IN_WORDS) != 0) { 2169 if ((flags & SIZE_IN_WORDS) != 0) {
2163 add(result_end, result, Operand(object_size, LSL, kPointerSizeLog2), SetCC); 2170 add(result_end, result, Operand(object_size, LSL, kPointerSizeLog2), SetCC);
2164 } else { 2171 } else {
2165 add(result_end, result, Operand(object_size), SetCC); 2172 add(result_end, result, Operand(object_size), SetCC);
2166 } 2173 }
2167 b(cs, gc_required); 2174
2168 cmp(result_end, Operand(alloc_limit)); 2175 cmp(result_end, Operand(alloc_limit));
2169 b(hi, gc_required); 2176 b(hi, gc_required);
2170 2177
2171 // Update allocation top. result temporarily holds the new top. 2178 // Update allocation top. result temporarily holds the new top.
2172 if (emit_debug_code()) { 2179 if (emit_debug_code()) {
2173 tst(result_end, Operand(kObjectAlignmentMask)); 2180 tst(result_end, Operand(kObjectAlignmentMask));
2174 Check(eq, kUnalignedAllocationInNewSpace); 2181 Check(eq, kUnalignedAllocationInNewSpace);
2175 } 2182 }
2176 str(result_end, MemOperand(top_address)); 2183 if ((flags & ALLOCATION_FOLDING_DOMINATOR) == 0) {
2184 // The top pointer is not updated for allocation folding dominators.
2185 str(result_end, MemOperand(top_address));
2186 }
2177 2187
2178 // Tag object. 2188 // Tag object.
2179 add(result, result, Operand(kHeapObjectTag)); 2189 add(result, result, Operand(kHeapObjectTag));
2180 } 2190 }
2181 2191
2192 void MacroAssembler::FastAllocate(Register object_size, Register result,
2193 Register result_end, Register scratch,
2194 AllocationFlags flags) {
2195 // |object_size| and |result_end| may overlap if the DOUBLE_ALIGNMENT flag
2196 // is not specified. Other registers must not overlap.
2197 DCHECK(!AreAliased(object_size, result, scratch, ip));
2198 DCHECK(!AreAliased(result_end, result, scratch, ip));
2199 DCHECK((flags & DOUBLE_ALIGNMENT) == 0 || !object_size.is(result_end));
2200
2201 ExternalReference allocation_top =
2202 AllocationUtils::GetAllocationTopReference(isolate(), flags);
2203
2204 Register top_address = scratch;
2205 mov(top_address, Operand(allocation_top));
2206 ldr(result, MemOperand(top_address));
2207
2208 if ((flags & DOUBLE_ALIGNMENT) != 0) {
2209 // Align the next allocation. Storing the filler map without checking top is
2210 // safe in new-space because the limit of the heap is aligned there.
2211 DCHECK(kPointerAlignment * 2 == kDoubleAlignment);
2212 and_(result_end, result, Operand(kDoubleAlignmentMask), SetCC);
2213 Label aligned;
2214 b(eq, &aligned);
2215 mov(result_end, Operand(isolate()->factory()->one_pointer_filler_map()));
2216 str(result_end, MemOperand(result, kDoubleSize / 2, PostIndex));
2217 bind(&aligned);
2218 }
2219
2220 // Calculate new top using result. Object size may be in words so a shift is
2221 // required to get the number of bytes.
2222 if ((flags & SIZE_IN_WORDS) != 0) {
2223 add(result_end, result, Operand(object_size, LSL, kPointerSizeLog2), SetCC);
2224 } else {
2225 add(result_end, result, Operand(object_size), SetCC);
2226 }
2227
2228 // Update allocation top. result temporarily holds the new top.
2229 if (emit_debug_code()) {
2230 tst(result_end, Operand(kObjectAlignmentMask));
2231 Check(eq, kUnalignedAllocationInNewSpace);
2232 }
2233 // The top pointer is not updated for allocation folding dominators.
2234 str(result_end, MemOperand(top_address));
2235
2236 add(result, result, Operand(kHeapObjectTag));
2237 }
2238
2239 void MacroAssembler::FastAllocate(int object_size, Register result,
2240 Register scratch1, Register scratch2,
2241 AllocationFlags flags) {
2242 DCHECK(object_size <= Page::kMaxRegularHeapObjectSize);
2243 DCHECK(!AreAliased(result, scratch1, scratch2, ip));
2244
2245 // Make object size into bytes.
2246 if ((flags & SIZE_IN_WORDS) != 0) {
2247 object_size *= kPointerSize;
2248 }
2249 DCHECK_EQ(0, object_size & kObjectAlignmentMask);
2250
2251 ExternalReference allocation_top =
2252 AllocationUtils::GetAllocationTopReference(isolate(), flags);
2253
2254 // Set up allocation top address register.
2255 Register top_address = scratch1;
2256 Register result_end = scratch2;
2257 mov(top_address, Operand(allocation_top));
2258 ldr(result, MemOperand(top_address));
2259
2260 if ((flags & DOUBLE_ALIGNMENT) != 0) {
2261 // Align the next allocation. Storing the filler map without checking top is
2262 // safe in new-space because the limit of the heap is aligned there.
2263 STATIC_ASSERT(kPointerAlignment * 2 == kDoubleAlignment);
2264 and_(result_end, result, Operand(kDoubleAlignmentMask), SetCC);
2265 Label aligned;
2266 b(eq, &aligned);
2267 mov(result_end, Operand(isolate()->factory()->one_pointer_filler_map()));
2268 str(result_end, MemOperand(result, kDoubleSize / 2, PostIndex));
2269 bind(&aligned);
2270 }
2271
2272 // Calculate new top using result. Object size may be in words so a shift is
2273 // required to get the number of bytes. We must preserve the ip register at
2274 // this point, so we cannot just use add().
2275 DCHECK(object_size > 0);
2276 Register source = result;
2277 Condition cond = al;
2278 int shift = 0;
2279 while (object_size != 0) {
2280 if (((object_size >> shift) & 0x03) == 0) {
2281 shift += 2;
2282 } else {
2283 int bits = object_size & (0xff << shift);
2284 object_size -= bits;
2285 shift += 8;
2286 Operand bits_operand(bits);
2287 DCHECK(bits_operand.instructions_required(this) == 1);
2288 add(result_end, source, bits_operand, LeaveCC, cond);
2289 source = result_end;
2290 cond = cc;
2291 }
2292 }
2293
2294 // The top pointer is not updated for allocation folding dominators.
2295 str(result_end, MemOperand(top_address));
2296
2297 add(result, result, Operand(kHeapObjectTag));
2298 }
2182 2299
2183 void MacroAssembler::AllocateTwoByteString(Register result, 2300 void MacroAssembler::AllocateTwoByteString(Register result,
2184 Register length, 2301 Register length,
2185 Register scratch1, 2302 Register scratch1,
2186 Register scratch2, 2303 Register scratch2,
2187 Register scratch3, 2304 Register scratch3,
2188 Label* gc_required) { 2305 Label* gc_required) {
2189 // Calculate the number of bytes needed for the characters in the string while 2306 // Calculate the number of bytes needed for the characters in the string while
2190 // observing object alignment. 2307 // observing object alignment.
2191 DCHECK((SeqTwoByteString::kHeaderSize & kObjectAlignmentMask) == 0); 2308 DCHECK((SeqTwoByteString::kHeaderSize & kObjectAlignmentMask) == 0);
(...skipping 1733 matching lines...) Expand 10 before | Expand all | Expand 10 after
3925 } 4042 }
3926 } 4043 }
3927 if (mag.shift > 0) mov(result, Operand(result, ASR, mag.shift)); 4044 if (mag.shift > 0) mov(result, Operand(result, ASR, mag.shift));
3928 add(result, result, Operand(dividend, LSR, 31)); 4045 add(result, result, Operand(dividend, LSR, 31));
3929 } 4046 }
3930 4047
3931 } // namespace internal 4048 } // namespace internal
3932 } // namespace v8 4049 } // namespace v8
3933 4050
3934 #endif // V8_TARGET_ARCH_ARM 4051 #endif // V8_TARGET_ARCH_ARM
OLDNEW
« no previous file with comments | « src/arm/macro-assembler-arm.h ('k') | src/arm64/macro-assembler-arm64.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698