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

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

Issue 1944001: Port inline swapping of elements for the sort function in array.js... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 10 years, 8 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/codegen-arm.h ('k') | src/arm/macro-assembler-arm.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/arm/codegen-arm.cc
===================================================================
--- src/arm/codegen-arm.cc (revision 4574)
+++ src/arm/codegen-arm.cc (working copy)
@@ -4507,6 +4507,28 @@
}
+class DeferredSwapElements: public DeferredCode {
+ public:
+ DeferredSwapElements(Register object, Register index1, Register index2)
+ : object_(object), index1_(index1), index2_(index2) {
+ set_comment("[ DeferredSwapElements");
+ }
+
+ virtual void Generate();
+
+ private:
+ Register object_, index1_, index2_;
+};
+
+
+void DeferredSwapElements::Generate() {
+ __ push(object_);
+ __ push(index1_);
+ __ push(index2_);
+ __ CallRuntime(Runtime::kSwapElements, 3);
+}
+
+
void CodeGenerator::GenerateSwapElements(ZoneList<Expression*>* args) {
Comment cmnt(masm_, "[ GenerateSwapElements");
@@ -4516,8 +4538,76 @@
Load(args->at(1));
Load(args->at(2));
- frame_->CallRuntime(Runtime::kSwapElements, 3);
- frame_->EmitPush(r0);
+ Register index2 = r2;
+ Register index1 = r1;
+ Register object = r0;
+ Register tmp1 = r3;
+ Register tmp2 = r4;
+
+ frame_->EmitPop(index2);
+ frame_->EmitPop(index1);
+ frame_->EmitPop(object);
+
+ DeferredSwapElements* deferred =
+ new DeferredSwapElements(object, index1, index2);
+
+ // Fetch the map and check if array is in fast case.
+ // Check that object doesn't require security checks and
+ // has no indexed interceptor.
+ __ CompareObjectType(object, tmp1, tmp2, FIRST_JS_OBJECT_TYPE);
+ deferred->Branch(lt);
+ __ ldrb(tmp2, FieldMemOperand(tmp1, Map::kBitFieldOffset));
+ __ tst(tmp2, Operand(KeyedLoadIC::kSlowCaseBitFieldMask));
+ deferred->Branch(nz);
+
+ // Check the object's elements are in fast case.
+ __ ldr(tmp1, FieldMemOperand(object, JSObject::kElementsOffset));
+ __ ldr(tmp2, FieldMemOperand(tmp1, HeapObject::kMapOffset));
+ __ LoadRoot(ip, Heap::kFixedArrayMapRootIndex);
+ __ cmp(tmp2, ip);
+ deferred->Branch(ne);
+
+ // Smi-tagging is equivalent to multiplying by 2.
+ STATIC_ASSERT(kSmiTag == 0);
+ STATIC_ASSERT(kSmiTagSize == 1);
+
+ // Check that both indices are smis.
+ __ mov(tmp2, index1);
+ __ orr(tmp2, tmp2, index2);
+ __ tst(tmp2, Operand(kSmiTagMask));
+ deferred->Branch(nz);
+
+ // Bring the offsets into the fixed array in tmp1 into index1 and
+ // index2.
+ __ mov(tmp2, Operand(FixedArray::kHeaderSize - kHeapObjectTag));
+ __ add(index1, tmp2, Operand(index1, LSL, kPointerSizeLog2 - kSmiTagSize));
+ __ add(index2, tmp2, Operand(index2, LSL, kPointerSizeLog2 - kSmiTagSize));
+
+ // Swap elements.
+ Register tmp3 = object;
+ object = no_reg;
+ __ ldr(tmp3, MemOperand(tmp1, index1));
+ __ ldr(tmp2, MemOperand(tmp1, index2));
+ __ str(tmp3, MemOperand(tmp1, index2));
+ __ str(tmp2, MemOperand(tmp1, index1));
+
+ Label done;
+ __ InNewSpace(tmp1, tmp2, eq, &done);
+ // Possible optimization: do a check that both values are Smis
+ // (or them and test against Smi mask.)
+
+ __ mov(tmp2, tmp1);
+ RecordWriteStub recordWrite1(tmp1, index1, tmp3);
+ __ CallStub(&recordWrite1);
+
+ RecordWriteStub recordWrite2(tmp2, index2, tmp3);
+ __ CallStub(&recordWrite2);
+
+ __ bind(&done);
+
+ deferred->BindExit();
+ __ LoadRoot(tmp1, Heap::kUndefinedValueRootIndex);
+ frame_->EmitPush(tmp1);
}
@@ -6503,6 +6593,12 @@
}
+void RecordWriteStub::Generate(MacroAssembler* masm) {
+ __ RecordWriteHelper(object_, offset_, scratch_);
+ __ Ret();
+}
+
+
// On entry r0 (rhs) and r1 (lhs) are the values to be compared.
// On exit r0 is 0, positive or negative to indicate the result of
// the comparison.
« no previous file with comments | « src/arm/codegen-arm.h ('k') | src/arm/macro-assembler-arm.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698