X64: Add inline SwapElements to fundamental code generator on x64 platform.
Review URL: http://codereview.chromium.org/6594074 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@6995 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
parent
7b0f5d4110
commit
505976cd53
@ -2952,7 +2952,73 @@ void FullCodeGenerator::EmitSwapElements(ZoneList<Expression*>* args) {
|
||||
VisitForStackValue(args->at(0));
|
||||
VisitForStackValue(args->at(1));
|
||||
VisitForStackValue(args->at(2));
|
||||
Label done;
|
||||
Label slow_case;
|
||||
Register object = rax;
|
||||
Register index_1 = rbx;
|
||||
Register index_2 = rcx;
|
||||
Register elements = rdi;
|
||||
Register temp = rdx;
|
||||
__ movq(object, Operand(rsp, 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.
|
||||
__ CmpObjectType(object, FIRST_JS_OBJECT_TYPE, temp);
|
||||
__ j(below, &slow_case);
|
||||
__ testb(FieldOperand(temp, Map::kBitFieldOffset),
|
||||
Immediate(KeyedLoadIC::kSlowCaseBitFieldMask));
|
||||
__ j(not_zero, &slow_case);
|
||||
|
||||
// Check the object's elements are in fast case and writable.
|
||||
__ movq(elements, FieldOperand(object, JSObject::kElementsOffset));
|
||||
__ CompareRoot(FieldOperand(elements, HeapObject::kMapOffset),
|
||||
Heap::kFixedArrayMapRootIndex);
|
||||
__ j(not_equal, &slow_case);
|
||||
|
||||
// Check that both indices are smis.
|
||||
__ movq(index_1, Operand(rsp, 1 * kPointerSize));
|
||||
__ movq(index_2, Operand(rsp, 0 * kPointerSize));
|
||||
__ JumpIfNotBothSmi(index_1, index_2, &slow_case);
|
||||
|
||||
// Check that both indices are valid.
|
||||
// The JSArray length field is a smi since the array is in fast case mode.
|
||||
__ movq(temp, FieldOperand(object, JSArray::kLengthOffset));
|
||||
__ SmiCompare(temp, index_1);
|
||||
__ j(below_equal, &slow_case);
|
||||
__ SmiCompare(temp, index_2);
|
||||
__ j(below_equal, &slow_case);
|
||||
|
||||
__ SmiToInteger32(index_1, index_1);
|
||||
__ SmiToInteger32(index_2, index_2);
|
||||
// Bring addresses into index1 and index2.
|
||||
__ lea(index_1, FieldOperand(elements, index_1, times_pointer_size,
|
||||
FixedArray::kHeaderSize));
|
||||
__ lea(index_2, FieldOperand(elements, index_2, times_pointer_size,
|
||||
FixedArray::kHeaderSize));
|
||||
|
||||
// Swap elements. Use object and temp as scratch registers.
|
||||
__ movq(object, Operand(index_1, 0));
|
||||
__ movq(temp, Operand(index_2, 0));
|
||||
__ movq(Operand(index_2, 0), object);
|
||||
__ movq(Operand(index_1, 0), temp);
|
||||
|
||||
Label new_space;
|
||||
__ InNewSpace(elements, temp, equal, &new_space);
|
||||
|
||||
__ movq(object, elements);
|
||||
__ RecordWriteHelper(object, index_1, temp);
|
||||
__ RecordWriteHelper(elements, index_2, temp);
|
||||
|
||||
__ bind(&new_space);
|
||||
// We are done. Drop elements from the stack, and return undefined.
|
||||
__ addq(rsp, Immediate(3 * kPointerSize));
|
||||
__ LoadRoot(rax, Heap::kUndefinedValueRootIndex);
|
||||
__ jmp(&done);
|
||||
|
||||
__ bind(&slow_case);
|
||||
__ CallRuntime(Runtime::kSwapElements, 3);
|
||||
|
||||
__ bind(&done);
|
||||
context()->Plug(rax);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user