Index: src/s390/macro-assembler-s390.cc |
diff --git a/src/s390/macro-assembler-s390.cc b/src/s390/macro-assembler-s390.cc |
index 70b3ca63549d2ce90485fb6484ed367562dc21c6..04c05eac9439564db48335aa17f84cc070fe851b 100644 |
--- a/src/s390/macro-assembler-s390.cc |
+++ b/src/s390/macro-assembler-s390.cc |
@@ -1579,25 +1579,18 @@ void MacroAssembler::Allocate(int object_size, Register result, |
// Set up allocation top address register. |
Register top_address = scratch1; |
- // This code stores a temporary value in ip. This is OK, as the code below |
- // does not need ip for implicit literal generation. |
- Register alloc_limit = ip; |
Register result_end = scratch2; |
mov(top_address, Operand(allocation_top)); |
if ((flags & RESULT_CONTAINS_TOP) == 0) { |
// Load allocation top into result and allocation limit into ip. |
LoadP(result, MemOperand(top_address)); |
- LoadP(alloc_limit, MemOperand(top_address, kPointerSize)); |
} else { |
if (emit_debug_code()) { |
// Assert that result actually contains top on entry. |
- LoadP(alloc_limit, MemOperand(top_address)); |
- CmpP(result, alloc_limit); |
+ CmpP(result, MemOperand(top_address)); |
Check(eq, kUnexpectedAllocationTop); |
} |
- // Load allocation limit. Result already contains allocation top. |
- LoadP(alloc_limit, MemOperand(top_address, limit - top)); |
} |
if ((flags & DOUBLE_ALIGNMENT) != 0) { |
@@ -1611,7 +1604,7 @@ void MacroAssembler::Allocate(int object_size, Register result, |
Label aligned; |
beq(&aligned, Label::kNear); |
if ((flags & PRETENURE) != 0) { |
- CmpLogicalP(result, alloc_limit); |
+ CmpLogicalP(result, MemOperand(top_address, limit - top)); |
bge(gc_required); |
} |
mov(result_end, Operand(isolate()->factory()->one_pointer_filler_map())); |
@@ -1621,27 +1614,24 @@ void MacroAssembler::Allocate(int object_size, Register result, |
#endif |
} |
- // Calculate new top and bail out if new space is exhausted. Use result |
- // to calculate the new top. |
- SubP(r0, alloc_limit, result); |
- if (is_int16(object_size)) { |
- CmpP(r0, Operand(object_size)); |
- blt(gc_required); |
- AddP(result_end, result, Operand(object_size)); |
- } else { |
- mov(result_end, Operand(object_size)); |
- CmpP(r0, result_end); |
- blt(gc_required); |
- AddP(result_end, result, result_end); |
- } |
+ AddP(result_end, result, Operand(object_size)); |
+ |
+ // Compare with allocation limit. |
+ CmpLogicalP(result_end, MemOperand(top_address, limit - top)); |
+ bge(gc_required); |
if ((flags & ALLOCATION_FOLDING_DOMINATOR) == 0) { |
// The top pointer is not updated for allocation folding dominators. |
StoreP(result_end, MemOperand(top_address)); |
} |
+ // Prefetch the allocation_top's next cache line in advance to |
+ // help alleviate potential cache misses. |
+ // Mode 2 - Prefetch the data into a cache line for store access. |
+ pfd(r2, MemOperand(result, 256)); |
+ |
// Tag object. |
- AddP(result, result, Operand(kHeapObjectTag)); |
+ la(result, MemOperand(result, kHeapObjectTag)); |
} |
void MacroAssembler::Allocate(Register object_size, Register result, |
@@ -1676,24 +1666,17 @@ void MacroAssembler::Allocate(Register object_size, Register result, |
// Set up allocation top address and allocation limit registers. |
Register top_address = scratch; |
- // This code stores a temporary value in ip. This is OK, as the code below |
- // does not need ip for implicit literal generation. |
- Register alloc_limit = ip; |
mov(top_address, Operand(allocation_top)); |
if ((flags & RESULT_CONTAINS_TOP) == 0) { |
- // Load allocation top into result and allocation limit into alloc_limit.. |
+ // Load allocation top into result |
LoadP(result, MemOperand(top_address)); |
- LoadP(alloc_limit, MemOperand(top_address, kPointerSize)); |
} else { |
if (emit_debug_code()) { |
// Assert that result actually contains top on entry. |
- LoadP(alloc_limit, MemOperand(top_address)); |
- CmpP(result, alloc_limit); |
+ CmpP(result, MemOperand(top_address)); |
Check(eq, kUnexpectedAllocationTop); |
} |
- // Load allocation limit. Result already contains allocation top. |
- LoadP(alloc_limit, MemOperand(top_address, limit - top)); |
} |
if ((flags & DOUBLE_ALIGNMENT) != 0) { |
@@ -1707,7 +1690,7 @@ void MacroAssembler::Allocate(Register object_size, Register result, |
Label aligned; |
beq(&aligned, Label::kNear); |
if ((flags & PRETENURE) != 0) { |
- CmpLogicalP(result, alloc_limit); |
+ CmpLogicalP(result, MemOperand(top_address, limit - top)); |
bge(gc_required); |
} |
mov(result_end, Operand(isolate()->factory()->one_pointer_filler_map())); |
@@ -1720,17 +1703,14 @@ void MacroAssembler::Allocate(Register object_size, Register result, |
// Calculate new top and bail out if new space is exhausted. Use result |
// to calculate the new top. Object size may be in words so a shift is |
// required to get the number of bytes. |
- SubP(r0, alloc_limit, result); |
if ((flags & SIZE_IN_WORDS) != 0) { |
ShiftLeftP(result_end, object_size, Operand(kPointerSizeLog2)); |
- CmpP(r0, result_end); |
- blt(gc_required); |
AddP(result_end, result, result_end); |
} else { |
- CmpP(r0, object_size); |
- blt(gc_required); |
AddP(result_end, result, object_size); |
} |
+ CmpLogicalP(result_end, MemOperand(top_address, limit - top)); |
+ bge(gc_required); |
// Update allocation top. result temporarily holds the new top. |
if (emit_debug_code()) { |
@@ -1742,8 +1722,13 @@ void MacroAssembler::Allocate(Register object_size, Register result, |
StoreP(result_end, MemOperand(top_address)); |
} |
+ // Prefetch the allocation_top's next cache line in advance to |
+ // help alleviate potential cache misses. |
+ // Mode 2 - Prefetch the data into a cache line for store access. |
+ pfd(r2, MemOperand(result, 256)); |
+ |
// Tag object. |
- AddP(result, result, Operand(kHeapObjectTag)); |
+ la(result, MemOperand(result, kHeapObjectTag)); |
} |
void MacroAssembler::FastAllocate(Register object_size, Register result, |
@@ -1795,8 +1780,13 @@ void MacroAssembler::FastAllocate(Register object_size, Register result, |
} |
StoreP(result_end, MemOperand(top_address)); |
+ // Prefetch the allocation_top's next cache line in advance to |
+ // help alleviate potential cache misses. |
+ // Mode 2 - Prefetch the data into a cache line for store access. |
+ pfd(r2, MemOperand(result, 256)); |
+ |
// Tag object. |
- AddP(result, result, Operand(kHeapObjectTag)); |
+ la(result, MemOperand(result, kHeapObjectTag)); |
} |
void MacroAssembler::FastAllocate(int object_size, Register result, |
@@ -1837,14 +1827,24 @@ void MacroAssembler::FastAllocate(int object_size, Register result, |
#endif |
} |
- // Calculate new top using result. |
- AddP(result_end, result, Operand(object_size)); |
+ if (CpuFeatures::IsSupported(GENERAL_INSTR_EXT) && is_int8(object_size)) { |
+ // Update allocation top. |
+ AddP(MemOperand(top_address), Operand(object_size)); |
+ } else { |
+ // Calculate new top using result. |
+ AddP(result_end, result, Operand(object_size)); |
- // The top pointer is not updated for allocation folding dominators. |
- StoreP(result_end, MemOperand(top_address)); |
+ // Update allocation top. |
+ StoreP(result_end, MemOperand(top_address)); |
+ } |
+ |
+ // Prefetch the allocation_top's next cache line in advance to |
+ // help alleviate potential cache misses. |
+ // Mode 2 - Prefetch the data into a cache line for store access. |
+ pfd(r2, MemOperand(result, 256)); |
// Tag object. |
- AddP(result, result, Operand(kHeapObjectTag)); |
+ la(result, MemOperand(result, kHeapObjectTag)); |
} |
void MacroAssembler::CompareObjectType(Register object, Register map, |