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

Unified Diff: src/arm/lithium-codegen-arm.cc

Issue 330053002: ARM, ARM64: Optimize array copy (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 6 years, 6 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/lithium-arm.cc ('k') | src/arm64/lithium-arm64.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/arm/lithium-codegen-arm.cc
diff --git a/src/arm/lithium-codegen-arm.cc b/src/arm/lithium-codegen-arm.cc
index 249c22f77bf3176b3e23583f3c29f1c02c274681..48c26526c0b9659d2c63880bea1051bf264dceea 100644
--- a/src/arm/lithium-codegen-arm.cc
+++ b/src/arm/lithium-codegen-arm.cc
@@ -4344,6 +4344,125 @@ void LCodeGen::DoStoreKeyedFixedArray(LStoreKeyed* instr) {
}
+void LCodeGen::DoFillElements(LFillElements* instr) {
+ Label end;
+ Register elements = ToRegister(instr->elements());
+ Register dst = scratch0();
+ ASSERT(instr->hydrogen()->to()->representation().IsInteger32());
+ ASSERT(instr->hydrogen()->from()->representation().IsInteger32());
+ int shift_size =
+ instr->value()->IsDoubleRegister() ? kDoubleSizeLog2 : kPointerSizeLog2;
+ // We will be able to skip the first test (which checks that we have at
+ // least one value to fill) if we know the number of values to copy.
+ bool skip_first_test = false;
+ Register remain;
+ if (instr->from()->IsConstantOperand()) {
+ int from = ToInteger32(LConstantOperand::cast(instr->from()));
+ int start_offset =
+ FixedDoubleArray::kHeaderSize - kHeapObjectTag + (from << shift_size);
+ if (instr->to()->IsConstantOperand()) {
+ int to = ToInteger32(LConstantOperand::cast(instr->to()));
+ if (instr->scratch() == NULL) {
+ // Scratch is null, if to - from was small enough to unroll the loop.
+ int max = to - from;
+ if (instr->value()->IsDoubleRegister()) {
+ __ add(dst, elements, Operand(start_offset));
+ DoubleRegister value = ToDoubleRegister(instr->value());
+ for (int count = 0; count < max; count++) {
+ __ vstr(value, dst, count * kDoubleSize);
+ }
+ } else {
+ Register value = ToRegister(instr->value());
+ for (int count = 0; count < max; count++) {
+ __ str(value,
+ MemOperand(elements, start_offset + count * kPointerSize));
+ }
+ }
+ __ bind(&end);
+ return;
+ }
+ __ add(dst, elements, Operand(start_offset));
+ skip_first_test = true;
+ remain = ToRegister(instr->scratch());
+ __ mov(remain, Operand(to - from));
+ } else {
+ remain = ToRegister(instr->scratch());
+ Register to = ToRegister(instr->to());
+ if (from == 0) {
+ __ mov(remain, Operand(to), SetCC);
+ } else {
+ __ sub(remain, to, Operand(from), SetCC);
+ }
+ __ add(dst, elements, Operand(start_offset));
+ }
+ } else {
+ remain = ToRegister(instr->scratch());
+ Register from = ToRegister(instr->from());
+ if (instr->to()->IsConstantOperand()) {
+ int to = ToInteger32(LConstantOperand::cast(instr->to()));
+ __ rsb(remain, from, Operand(to), SetCC);
+ } else {
+ Register to = ToRegister(instr->to());
+ __ sub(remain, to, Operand(from), SetCC);
+ }
+ __ add(dst, elements,
+ Operand(FixedDoubleArray::kHeaderSize - kHeapObjectTag));
+ __ add(dst, dst, Operand(from, LSL, shift_size));
+ }
+ Label loop, done;
+ if (!skip_first_test) {
+ __ b(le, &done);
+ }
+ __ bind(&loop);
+ __ sub(remain, remain, Operand(1), SetCC);
+ if (instr->value()->IsDoubleRegister()) {
+ DoubleRegister value = ToDoubleRegister(instr->value());
+ __ vstr(value, dst, 0);
+ __ add(dst, dst, Operand(kDoubleSize));
+ } else {
+ Register value = ToRegister(instr->value());
+ __ str(value, MemOperand(dst, kPointerSize, PostIndex));
+ }
+ __ b(gt, &loop);
+ if (!skip_first_test) {
+ __ bind(&done);
+ }
+ __ bind(&end);
+}
+
+
+void LCodeGen::DoCopyElements(LCopyElements* instr) {
+ Label loop, done;
+ Register dst = ToRegister(instr->dst());
+ Register src = ToRegister(instr->src());
+ Register length = ToRegister(instr->length());
+ __ cmp(length, Operand::Zero());
+ __ add(src, src, Operand(FixedDoubleArray::kHeaderSize - kHeapObjectTag));
+ __ add(dst, dst,
+ Operand(FixedDoubleArray::kHeaderSize - kHeapObjectTag));
+ __ b(eq, &done);
+ __ bind(&loop);
+ if (instr->hydrogen()->length()->representation().IsSmi()) {
+ __ sub(length, length, Operand(Smi::FromInt(1)), SetCC);
+ } else {
+ __ sub(length, length, Operand(1), SetCC);
+ }
+ if (IsFastSmiOrObjectElementsKind(instr->elements_kind())) {
+ Register value = scratch0();
+ __ ldr(value, MemOperand(src, kPointerSize, PostIndex));
+ __ str(value, MemOperand(dst, kPointerSize, PostIndex));
+ } else {
+ DoubleRegister value = double_scratch0();
+ __ vldr(value, src, 0);
+ __ vstr(value, dst, 0);
+ __ add(src, src, Operand(kDoubleSize));
+ __ add(dst, dst, Operand(kDoubleSize));
+ }
+ __ b(gt, &loop);
+ __ bind(&done);
+}
+
+
void LCodeGen::DoStoreKeyed(LStoreKeyed* instr) {
// By cases: external, fast double
if (instr->is_typed_elements()) {
« no previous file with comments | « src/arm/lithium-arm.cc ('k') | src/arm64/lithium-arm64.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698