Chromium Code Reviews| Index: src/arm/full-codegen-arm.cc |
| =================================================================== |
| --- src/arm/full-codegen-arm.cc (revision 7028) |
| +++ src/arm/full-codegen-arm.cc (working copy) |
| @@ -3113,7 +3113,80 @@ |
| VisitForStackValue(args->at(0)); |
| VisitForStackValue(args->at(1)); |
| VisitForStackValue(args->at(2)); |
| + Label done; |
| + Label slow_case; |
| + Register object = r0; |
| + Register index1 = r1; |
| + Register index2 = r2; |
| + Register elements = r3; |
| + Register scratch1 = r4; |
| + Register scratch2 = r5; |
| + |
| + __ ldr(object, MemOperand(sp, 2 * kPointerSize)); |
| + // 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, scratch1, scratch2, FIRST_JS_OBJECT_TYPE); |
| + __ b(lt, &slow_case); |
| + // Map is now in scratch1. |
| + |
| + __ ldrb(scratch2, FieldMemOperand(scratch1, Map::kBitFieldOffset)); |
| + __ tst(scratch2, Operand(KeyedLoadIC::kSlowCaseBitFieldMask)); |
| + __ b(ne, &slow_case); |
| + |
| + // Check the object's elements are in fast case and writable. |
|
Karl Klose
2011/03/02 15:04:39
What does writable mean here?
Søren Thygesen Gjesse
2011/03/03 07:34:31
It means that it is not copy-on-write (copy-on-wri
|
| + __ ldr(elements, FieldMemOperand(object, JSObject::kElementsOffset)); |
| + __ ldr(scratch1, FieldMemOperand(elements, HeapObject::kMapOffset)); |
| + __ LoadRoot(ip, Heap::kFixedArrayMapRootIndex); |
| + __ cmp(scratch1, ip); |
| + __ b(ne, &slow_case); |
| + |
| + // Check that both indices are smis. |
| + __ ldr(index1, MemOperand(sp, 1 * kPointerSize)); |
| + __ ldr(index2, MemOperand(sp, 0)); |
| + __ JumpIfNotBothSmi(index1, index2, &slow_case); |
| + |
| + // Check that both indices are valid. |
| + __ ldr(scratch1, FieldMemOperand(object, JSArray::kLengthOffset)); |
| + __ cmp(scratch1, index1); |
| + __ cmp(scratch1, index2, hi); |
| + __ b(ls, &slow_case); |
| + |
| + // Bring the address of the elements into index1 and index2. |
| + __ add(scratch1, elements, Operand(FixedArray::kHeaderSize - kHeapObjectTag)); |
| + __ add(index1, |
| + scratch1, |
| + Operand(index1, LSL, kPointerSizeLog2 - kSmiTagSize)); |
| + __ add(index2, |
| + scratch1, |
| + Operand(index2, LSL, kPointerSizeLog2 - kSmiTagSize)); |
| + |
| + // Swap elements. |
| + __ ldr(scratch1, MemOperand(index1, 0)); |
| + __ ldr(scratch2, MemOperand(index2, 0))); |
| + __ str(scratch1, MemOperand(index2, 0)); |
| + __ str(scratch2, MemOperand(index1, 0)); |
| + |
| + Label new_space; |
| + __ InNewSpace(elements, scratch1, eq, &new_space); |
| + // Possible optimization: do a check that both values are Smis |
| + // (or them and test against Smi mask.) |
| + |
| + __ mov(scratch1, elements); |
| + __ RecordWriteHelper(elements, index1, scratch2); |
| + __ RecordWriteHelper(scratch1, index2, scratch2); // scratch1 holds elements. |
| + __ bind(&done); |
| + |
| + __ bind(&new_space); |
| + // We are done. Drop elements from the stack, and return undefined. |
| + __ Drop(3); |
| + __ LoadRoot(r0, Heap::kUndefinedValueRootIndex); |
| + __ jmp(&done); |
| + |
| + __ bind(&slow_case); |
| __ CallRuntime(Runtime::kSwapElements, 3); |
| + |
| + __ bind(&done); |
| context()->Plug(r0); |
| } |