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

Unified 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 side-by-side diff with in-line comments
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 »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/arm/macro-assembler-arm.cc
diff --git a/src/arm/macro-assembler-arm.cc b/src/arm/macro-assembler-arm.cc
index f7b57300937a8e7e0eced51d591b221f9781d8ff..e7e1ea5e323688a114da863d1ddeaa58c69c9c60 100644
--- a/src/arm/macro-assembler-arm.cc
+++ b/src/arm/macro-assembler-arm.cc
@@ -1985,6 +1985,7 @@ void MacroAssembler::Allocate(int object_size,
Label* gc_required,
AllocationFlags flags) {
DCHECK(object_size <= Page::kMaxRegularHeapObjectSize);
+ DCHECK((flags & ALLOCATION_FOLDED) == 0);
if (!FLAG_inline_new) {
if (emit_debug_code()) {
// Trash the registers to simulate an allocation failure.
@@ -2077,9 +2078,14 @@ void MacroAssembler::Allocate(int object_size,
cond = cc;
}
}
+
cmp(result_end, Operand(alloc_limit));
b(hi, gc_required);
- str(result_end, MemOperand(top_address));
+
+ if ((flags & ALLOCATION_FOLDING_DOMINATOR) == 0) {
+ // The top pointer is not updated for allocation folding dominators.
+ str(result_end, MemOperand(top_address));
+ }
// Tag object.
add(result, result, Operand(kHeapObjectTag));
@@ -2089,6 +2095,7 @@ void MacroAssembler::Allocate(int object_size,
void MacroAssembler::Allocate(Register object_size, Register result,
Register result_end, Register scratch,
Label* gc_required, AllocationFlags flags) {
+ DCHECK((flags & ALLOCATION_FOLDED) == 0);
if (!FLAG_inline_new) {
if (emit_debug_code()) {
// Trash the registers to simulate an allocation failure.
@@ -2164,7 +2171,7 @@ void MacroAssembler::Allocate(Register object_size, Register result,
} else {
add(result_end, result, Operand(object_size), SetCC);
}
- b(cs, gc_required);
+
cmp(result_end, Operand(alloc_limit));
b(hi, gc_required);
@@ -2173,12 +2180,122 @@ void MacroAssembler::Allocate(Register object_size, Register result,
tst(result_end, Operand(kObjectAlignmentMask));
Check(eq, kUnalignedAllocationInNewSpace);
}
- str(result_end, MemOperand(top_address));
+ if ((flags & ALLOCATION_FOLDING_DOMINATOR) == 0) {
+ // The top pointer is not updated for allocation folding dominators.
+ str(result_end, MemOperand(top_address));
+ }
// Tag object.
add(result, result, Operand(kHeapObjectTag));
}
+void MacroAssembler::FastAllocate(Register object_size, Register result,
+ Register result_end, Register scratch,
+ AllocationFlags flags) {
+ // |object_size| and |result_end| may overlap if the DOUBLE_ALIGNMENT flag
+ // is not specified. Other registers must not overlap.
+ DCHECK(!AreAliased(object_size, result, scratch, ip));
+ DCHECK(!AreAliased(result_end, result, scratch, ip));
+ DCHECK((flags & DOUBLE_ALIGNMENT) == 0 || !object_size.is(result_end));
+
+ ExternalReference allocation_top =
+ AllocationUtils::GetAllocationTopReference(isolate(), flags);
+
+ Register top_address = scratch;
+ mov(top_address, Operand(allocation_top));
+ ldr(result, MemOperand(top_address));
+
+ if ((flags & DOUBLE_ALIGNMENT) != 0) {
+ // Align the next allocation. Storing the filler map without checking top is
+ // safe in new-space because the limit of the heap is aligned there.
+ DCHECK(kPointerAlignment * 2 == kDoubleAlignment);
+ and_(result_end, result, Operand(kDoubleAlignmentMask), SetCC);
+ Label aligned;
+ b(eq, &aligned);
+ mov(result_end, Operand(isolate()->factory()->one_pointer_filler_map()));
+ str(result_end, MemOperand(result, kDoubleSize / 2, PostIndex));
+ bind(&aligned);
+ }
+
+ // Calculate new top using result. Object size may be in words so a shift is
+ // required to get the number of bytes.
+ if ((flags & SIZE_IN_WORDS) != 0) {
+ add(result_end, result, Operand(object_size, LSL, kPointerSizeLog2), SetCC);
+ } else {
+ add(result_end, result, Operand(object_size), SetCC);
+ }
+
+ // Update allocation top. result temporarily holds the new top.
+ if (emit_debug_code()) {
+ tst(result_end, Operand(kObjectAlignmentMask));
+ Check(eq, kUnalignedAllocationInNewSpace);
+ }
+ // The top pointer is not updated for allocation folding dominators.
+ str(result_end, MemOperand(top_address));
+
+ add(result, result, Operand(kHeapObjectTag));
+}
+
+void MacroAssembler::FastAllocate(int object_size, Register result,
+ Register scratch1, Register scratch2,
+ AllocationFlags flags) {
+ DCHECK(object_size <= Page::kMaxRegularHeapObjectSize);
+ DCHECK(!AreAliased(result, scratch1, scratch2, ip));
+
+ // Make object size into bytes.
+ if ((flags & SIZE_IN_WORDS) != 0) {
+ object_size *= kPointerSize;
+ }
+ DCHECK_EQ(0, object_size & kObjectAlignmentMask);
+
+ ExternalReference allocation_top =
+ AllocationUtils::GetAllocationTopReference(isolate(), flags);
+
+ // Set up allocation top address register.
+ Register top_address = scratch1;
+ Register result_end = scratch2;
+ mov(top_address, Operand(allocation_top));
+ ldr(result, MemOperand(top_address));
+
+ if ((flags & DOUBLE_ALIGNMENT) != 0) {
+ // Align the next allocation. Storing the filler map without checking top is
+ // safe in new-space because the limit of the heap is aligned there.
+ STATIC_ASSERT(kPointerAlignment * 2 == kDoubleAlignment);
+ and_(result_end, result, Operand(kDoubleAlignmentMask), SetCC);
+ Label aligned;
+ b(eq, &aligned);
+ mov(result_end, Operand(isolate()->factory()->one_pointer_filler_map()));
+ str(result_end, MemOperand(result, kDoubleSize / 2, PostIndex));
+ bind(&aligned);
+ }
+
+ // Calculate new top using result. Object size may be in words so a shift is
+ // required to get the number of bytes. We must preserve the ip register at
+ // this point, so we cannot just use add().
+ DCHECK(object_size > 0);
+ Register source = result;
+ Condition cond = al;
+ int shift = 0;
+ while (object_size != 0) {
+ if (((object_size >> shift) & 0x03) == 0) {
+ shift += 2;
+ } else {
+ int bits = object_size & (0xff << shift);
+ object_size -= bits;
+ shift += 8;
+ Operand bits_operand(bits);
+ DCHECK(bits_operand.instructions_required(this) == 1);
+ add(result_end, source, bits_operand, LeaveCC, cond);
+ source = result_end;
+ cond = cc;
+ }
+ }
+
+ // The top pointer is not updated for allocation folding dominators.
+ str(result_end, MemOperand(top_address));
+
+ add(result, result, Operand(kHeapObjectTag));
+}
void MacroAssembler::AllocateTwoByteString(Register result,
Register length,
« 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