ARM: Small copy optimization. Copying 64bits at a time.
BUG=none TEST=none Review URL: https://chromiumcodereview.appspot.com/14121006 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@14254 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
parent
f5b660ac97
commit
ee7bdef143
@ -212,6 +212,7 @@ const Register pc = { kRegister_pc_Code };
|
|||||||
|
|
||||||
// Single word VFP register.
|
// Single word VFP register.
|
||||||
struct SwVfpRegister {
|
struct SwVfpRegister {
|
||||||
|
static const int kSizeInBytes = 4;
|
||||||
bool is_valid() const { return 0 <= code_ && code_ < 32; }
|
bool is_valid() const { return 0 <= code_ && code_ < 32; }
|
||||||
bool is(SwVfpRegister reg) const { return code_ == reg.code_; }
|
bool is(SwVfpRegister reg) const { return code_ == reg.code_; }
|
||||||
int code() const {
|
int code() const {
|
||||||
@ -242,6 +243,7 @@ struct DwVfpRegister {
|
|||||||
static const int kNumReservedRegisters = 2;
|
static const int kNumReservedRegisters = 2;
|
||||||
static const int kMaxNumAllocatableRegisters = kMaxNumRegisters -
|
static const int kMaxNumAllocatableRegisters = kMaxNumRegisters -
|
||||||
kNumReservedRegisters;
|
kNumReservedRegisters;
|
||||||
|
static const int kSizeInBytes = 8;
|
||||||
|
|
||||||
// Note: the number of registers can be different at snapshot and run-time.
|
// Note: the number of registers can be different at snapshot and run-time.
|
||||||
// Any code included in the snapshot must be able to run both with 16 or 32
|
// Any code included in the snapshot must be able to run both with 16 or 32
|
||||||
|
@ -4448,7 +4448,7 @@ void ArgumentsAccessStub::GenerateNewStrict(MacroAssembler* masm) {
|
|||||||
Context::STRICT_MODE_ARGUMENTS_BOILERPLATE_INDEX)));
|
Context::STRICT_MODE_ARGUMENTS_BOILERPLATE_INDEX)));
|
||||||
|
|
||||||
// Copy the JS object part.
|
// Copy the JS object part.
|
||||||
__ CopyFields(r0, r4, r3.bit(), JSObject::kHeaderSize / kPointerSize);
|
__ CopyFields(r0, r4, d0, s0, JSObject::kHeaderSize / kPointerSize);
|
||||||
|
|
||||||
// Get the length (smi tagged) and set that as an in-object property too.
|
// Get the length (smi tagged) and set that as an in-object property too.
|
||||||
STATIC_ASSERT(Heap::kArgumentsLengthIndex == 0);
|
STATIC_ASSERT(Heap::kArgumentsLengthIndex == 0);
|
||||||
|
@ -1563,7 +1563,7 @@ void FullCodeGenerator::VisitRegExpLiteral(RegExpLiteral* expr) {
|
|||||||
// r0: Newly allocated regexp.
|
// r0: Newly allocated regexp.
|
||||||
// r5: Materialized regexp.
|
// r5: Materialized regexp.
|
||||||
// r2: temp.
|
// r2: temp.
|
||||||
__ CopyFields(r0, r5, r2.bit(), size / kPointerSize);
|
__ CopyFields(r0, r5, d0, s0, size / kPointerSize);
|
||||||
context()->Plug(r0);
|
context()->Plug(r0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5614,17 +5614,8 @@ void LCodeGen::DoRegExpLiteral(LRegExpLiteral* instr) {
|
|||||||
|
|
||||||
__ bind(&allocated);
|
__ bind(&allocated);
|
||||||
// Copy the content into the newly allocated memory.
|
// Copy the content into the newly allocated memory.
|
||||||
// (Unroll copy loop once for better throughput).
|
__ CopyFields(r0, r1, double_scratch0(), double_scratch0().low(),
|
||||||
for (int i = 0; i < size - kPointerSize; i += 2 * kPointerSize) {
|
size / kPointerSize);
|
||||||
__ ldr(r3, FieldMemOperand(r1, i));
|
|
||||||
__ ldr(r2, FieldMemOperand(r1, i + kPointerSize));
|
|
||||||
__ str(r3, FieldMemOperand(r0, i));
|
|
||||||
__ str(r2, FieldMemOperand(r0, i + kPointerSize));
|
|
||||||
}
|
|
||||||
if ((size % (2 * kPointerSize)) != 0) {
|
|
||||||
__ ldr(r3, FieldMemOperand(r1, size - kPointerSize));
|
|
||||||
__ str(r3, FieldMemOperand(r0, size - kPointerSize));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -3160,27 +3160,24 @@ void MacroAssembler::AllocateHeapNumberWithValue(Register result,
|
|||||||
// Copies a fixed number of fields of heap objects from src to dst.
|
// Copies a fixed number of fields of heap objects from src to dst.
|
||||||
void MacroAssembler::CopyFields(Register dst,
|
void MacroAssembler::CopyFields(Register dst,
|
||||||
Register src,
|
Register src,
|
||||||
RegList temps,
|
DwVfpRegister double_scratch,
|
||||||
|
SwVfpRegister single_scratch,
|
||||||
int field_count) {
|
int field_count) {
|
||||||
// At least one bit set in the first 15 registers.
|
int double_count = field_count / (DwVfpRegister::kSizeInBytes / kPointerSize);
|
||||||
ASSERT((temps & ((1 << 15) - 1)) != 0);
|
for (int i = 0; i < double_count; i++) {
|
||||||
ASSERT((temps & dst.bit()) == 0);
|
vldr(double_scratch, FieldMemOperand(src, i * DwVfpRegister::kSizeInBytes));
|
||||||
ASSERT((temps & src.bit()) == 0);
|
vstr(double_scratch, FieldMemOperand(dst, i * DwVfpRegister::kSizeInBytes));
|
||||||
// Primitive implementation using only one temporary register.
|
|
||||||
|
|
||||||
Register tmp = no_reg;
|
|
||||||
// Find a temp register in temps list.
|
|
||||||
for (int i = 0; i < 15; i++) {
|
|
||||||
if ((temps & (1 << i)) != 0) {
|
|
||||||
tmp.set_code(i);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
ASSERT(!tmp.is(no_reg));
|
|
||||||
|
|
||||||
for (int i = 0; i < field_count; i++) {
|
STATIC_ASSERT(SwVfpRegister::kSizeInBytes == kPointerSize);
|
||||||
ldr(tmp, FieldMemOperand(src, i * kPointerSize));
|
STATIC_ASSERT(2 * SwVfpRegister::kSizeInBytes == DwVfpRegister::kSizeInBytes);
|
||||||
str(tmp, FieldMemOperand(dst, i * kPointerSize));
|
|
||||||
|
int remain = field_count % (DwVfpRegister::kSizeInBytes / kPointerSize);
|
||||||
|
if (remain != 0) {
|
||||||
|
vldr(single_scratch,
|
||||||
|
FieldMemOperand(src, (field_count - 1) * kPointerSize));
|
||||||
|
vstr(single_scratch,
|
||||||
|
FieldMemOperand(dst, (field_count - 1) * kPointerSize));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -743,7 +743,11 @@ class MacroAssembler: public Assembler {
|
|||||||
Label* gc_required);
|
Label* gc_required);
|
||||||
|
|
||||||
// Copies a fixed number of fields of heap objects from src to dst.
|
// Copies a fixed number of fields of heap objects from src to dst.
|
||||||
void CopyFields(Register dst, Register src, RegList temps, int field_count);
|
void CopyFields(Register dst,
|
||||||
|
Register src,
|
||||||
|
DwVfpRegister double_scratch,
|
||||||
|
SwVfpRegister single_scratch,
|
||||||
|
int field_count);
|
||||||
|
|
||||||
// Copies a number of bytes from src to dst. All registers are clobbered. On
|
// Copies a number of bytes from src to dst. All registers are clobbered. On
|
||||||
// exit src and dst will point to the place just after where the last byte was
|
// exit src and dst will point to the place just after where the last byte was
|
||||||
|
Loading…
Reference in New Issue
Block a user