Revision: 3000
Author: [email protected]
Date: Wed Sep 30 13:18:40 2009
Log: Add pixel array handling in keyed IC's for x64 version.
Review URL: http://codereview.chromium.org/251041
http://code.google.com/p/v8/source/detail?r=3000
Modified:
/branches/bleeding_edge/src/ia32/ic-ia32.cc
/branches/bleeding_edge/src/x64/ic-x64.cc
/branches/bleeding_edge/src/x64/macro-assembler-x64.cc
/branches/bleeding_edge/src/x64/macro-assembler-x64.h
=======================================
--- /branches/bleeding_edge/src/ia32/ic-ia32.cc Tue Sep 29 07:56:24 2009
+++ /branches/bleeding_edge/src/ia32/ic-ia32.cc Wed Sep 30 13:18:40 2009
@@ -424,15 +424,14 @@
__ mov(edx, eax); // Save the value.
__ sar(eax, kSmiTagSize); // Untag the value.
{ // Clamp the value to [0..255].
- Label done, check_255;
- __ cmp(eax, 0);
- __ j(greater_equal, &check_255);
- __ mov(eax, Immediate(0));
- __ jmp(&done);
- __ bind(&check_255);
- __ cmp(eax, 255);
- __ j(less_equal, &done);
+ Label done, is_negative;
+ __ test(eax, Immediate(0xFFFFFF00));
+ __ j(zero, &done);
+ __ j(negative, &is_negative);
__ mov(eax, Immediate(255));
+ __ jmp(&done);
+ __ bind(&is_negative);
+ __ xor_(eax, Operand(eax)); // Clear eax.
__ bind(&done);
}
__ mov(ecx, FieldOperand(ecx, PixelArray::kExternalPointerOffset));
=======================================
--- /branches/bleeding_edge/src/x64/ic-x64.cc Fri Sep 11 05:41:27 2009
+++ /branches/bleeding_edge/src/x64/ic-x64.cc Wed Sep 30 13:18:40 2009
@@ -257,7 +257,7 @@
// -- rsp[8] : name
// -- rsp[16] : receiver
// -----------------------------------
- Label slow, fast, check_string, index_int, index_string;
+ Label slow, check_string, index_int, index_string, check_pixel_array;
// Load name and receiver.
__ movq(rax, Operand(rsp, kPointerSize));
@@ -287,11 +287,36 @@
__ bind(&index_int);
__ movq(rcx, FieldOperand(rcx, JSObject::kElementsOffset));
// Check that the object is in fast mode (not dictionary).
- __ Cmp(FieldOperand(rcx, HeapObject::kMapOffset),
Factory::fixed_array_map());
- __ j(not_equal, &slow);
+ __ CompareRoot(FieldOperand(rcx, HeapObject::kMapOffset),
+ Heap::kFixedArrayMapRootIndex);
+ __ j(not_equal, &check_pixel_array);
// Check that the key (index) is within bounds.
__ cmpl(rax, FieldOperand(rcx, FixedArray::kLengthOffset));
- __ j(below, &fast); // Unsigned comparison rejects negative indices.
+ __ j(above_equal, &slow); // Unsigned comparison rejects negative
indices.
+ // Fast case: Do the load.
+ __ movq(rax, Operand(rcx, rax, times_pointer_size,
+ FixedArray::kHeaderSize - kHeapObjectTag));
+ __ CompareRoot(rax, Heap::kTheHoleValueRootIndex);
+ // In case the loaded value is the_hole we have to consult GetProperty
+ // to ensure the prototype chain is searched.
+ __ j(equal, &slow);
+ __ IncrementCounter(&Counters::keyed_load_generic_smi, 1);
+ __ ret(0);
+
+ // Check whether the elements is a pixel array.
+ // rax: untagged index
+ // rcx: elements array
+ __ bind(&check_pixel_array);
+ __ CompareRoot(FieldOperand(rcx, HeapObject::kMapOffset),
+ Heap::kPixelArrayMapRootIndex);
+ __ j(not_equal, &slow);
+ __ cmpl(rax, FieldOperand(rcx, PixelArray::kLengthOffset));
+ __ j(above_equal, &slow);
+ __ movq(rcx, FieldOperand(rcx, PixelArray::kExternalPointerOffset));
+ __ movb(rax, Operand(rcx, rax, times_1, 0));
+ __ Integer32ToSmi(rax, rax);
+ __ ret(0);
+
// Slow case: Load name and receiver from stack and jump to runtime.
__ bind(&slow);
__ IncrementCounter(&Counters::keyed_load_generic_slow, 1);
@@ -332,16 +357,6 @@
__ and_(rax, Immediate((1 << String::kShortLengthShift) - 1));
__ shrl(rax, Immediate(String::kLongLengthShift));
__ jmp(&index_int);
- // Fast case: Do the load.
- __ bind(&fast);
- __ movq(rax, Operand(rcx, rax, times_pointer_size,
- FixedArray::kHeaderSize - kHeapObjectTag));
- __ CompareRoot(rax, Heap::kTheHoleValueRootIndex);
- // In case the loaded value is the_hole we have to consult GetProperty
- // to ensure the prototype chain is searched.
- __ j(equal, &slow);
- __ IncrementCounter(&Counters::keyed_load_generic_smi, 1);
- __ ret(0);
}
@@ -402,7 +417,7 @@
// -- rsp[8] : key
// -- rsp[16] : receiver
// -----------------------------------
- Label slow, fast, array, extra;
+ Label slow, fast, array, extra, check_pixel_array;
// Get the receiver from the stack.
__ movq(rdx, Operand(rsp, 2 * kPointerSize)); // 2 ~ return address, key
@@ -435,8 +450,9 @@
// rbx: index (as a smi), zero-extended.
__ movq(rcx, FieldOperand(rdx, JSObject::kElementsOffset));
// Check that the object is in fast mode (not dictionary).
- __ Cmp(FieldOperand(rcx, HeapObject::kMapOffset),
Factory::fixed_array_map());
- __ j(not_equal, &slow);
+ __ CompareRoot(FieldOperand(rcx, HeapObject::kMapOffset),
+ Heap::kFixedArrayMapRootIndex);
+ __ j(not_equal, &check_pixel_array);
// Untag the key (for checking against untagged length in the fixed
array).
__ SmiToInteger32(rdx, rbx);
__ cmpl(rdx, FieldOperand(rcx, Array::kLengthOffset));
@@ -445,7 +461,6 @@
// rbx: index (as a smi)
__ j(below, &fast);
-
// Slow case: Push extra copies of the arguments (3).
__ bind(&slow);
__ pop(rcx);
@@ -456,6 +471,37 @@
// Do tail-call to runtime routine.
__ TailCallRuntime(ExternalReference(Runtime::kSetProperty), 3, 1);
+ // Check whether the elements is a pixel array.
+ // rax: value
+ // rcx: elements array
+ // rbx: index (as a smi), zero-extended.
+ __ bind(&check_pixel_array);
+ __ CompareRoot(FieldOperand(rcx, HeapObject::kMapOffset),
+ Heap::kPixelArrayMapRootIndex);
+ __ j(not_equal, &slow);
+ // Check that the value is a smi. If a conversion is needed call into the
+ // runtime to convert and clamp.
+ __ JumpIfNotSmi(rax, &slow);
+ __ SmiToInteger32(rbx, rbx);
+ __ cmpl(rbx, FieldOperand(rcx, PixelArray::kLengthOffset));
+ __ j(above_equal, &slow);
+ __ movq(rdx, rax); // Save the value.
+ __ SmiToInteger32(rax, rax);
+ { // Clamp the value to [0..255].
+ Label done, is_negative;
+ __ testl(rax, Immediate(0xFFFFFF00));
+ __ j(zero, &done);
+ __ j(negative, &is_negative);
+ __ movl(rax, Immediate(255));
+ __ jmp(&done);
+ __ bind(&is_negative);
+ __ xorl(rax, rax); // Clear rax.
+ __ bind(&done);
+ }
+ __ movq(rcx, FieldOperand(rcx, PixelArray::kExternalPointerOffset));
+ __ movb(Operand(rcx, rbx, times_1, 0), rax);
+ __ movq(rax, rdx); // Return the original value.
+ __ ret(0);
// Extra capacity case: Check if there is extra capacity to
// perform the store and update the length. Used for adding one
@@ -476,7 +522,6 @@
__ SmiSubConstant(rbx, rbx, 1, NULL);
__ jmp(&fast);
-
// Array case: Get the length and the elements array from the JS
// array. Check that the array is in fast mode; if it is the
// length is always a smi.
@@ -493,7 +538,6 @@
__ cmpl(rbx, FieldOperand(rdx, JSArray::kLengthOffset));
__ j(above_equal, &extra);
-
// Fast case: Do the store.
__ bind(&fast);
// rax: value
=======================================
--- /branches/bleeding_edge/src/x64/macro-assembler-x64.cc Wed Sep 30
02:24:46 2009
+++ /branches/bleeding_edge/src/x64/macro-assembler-x64.cc Wed Sep 30
13:18:40 2009
@@ -61,6 +61,13 @@
Heap::RootListIndex index) {
cmpq(with, Operand(r13, index << kPointerSizeLog2));
}
+
+
+void MacroAssembler::CompareRoot(Operand with,
+ Heap::RootListIndex index) {
+ LoadRoot(kScratchRegister, index);
+ cmpq(with, kScratchRegister);
+}
static void RecordWriteHelper(MacroAssembler* masm,
=======================================
--- /branches/bleeding_edge/src/x64/macro-assembler-x64.h Wed Sep 30
02:24:46 2009
+++ /branches/bleeding_edge/src/x64/macro-assembler-x64.h Wed Sep 30
13:18:40 2009
@@ -56,6 +56,7 @@
void LoadRoot(Register destination, Heap::RootListIndex index);
void CompareRoot(Register with, Heap::RootListIndex index);
+ void CompareRoot(Operand with, Heap::RootListIndex index);
void PushRoot(Heap::RootListIndex index);
//
---------------------------------------------------------------------------
--~--~---------~--~----~------------~-------~--~----~
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
-~----------~----~----~----~------~----~------~--~---