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

Unified Diff: src/arm/stub-cache-arm.cc

Issue 7307030: Implement ICs for FastDoubleArray loads and stores (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Fix nit Created 9 years, 5 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
Index: src/arm/stub-cache-arm.cc
diff --git a/src/arm/stub-cache-arm.cc b/src/arm/stub-cache-arm.cc
index 86e49716d3b45e3c91dc5b89b4a886a81b5ebdf4..a883b37dc07e72a04ef87a84eb4804493c1457a9 100644
--- a/src/arm/stub-cache-arm.cc
+++ b/src/arm/stub-cache-arm.cc
@@ -4168,6 +4168,70 @@ void KeyedLoadStubCompiler::GenerateLoadFastElement(MacroAssembler* masm) {
}
+void KeyedLoadStubCompiler::GenerateLoadFastDoubleElement(
+ MacroAssembler* masm) {
+ // ----------- S t a t e -------------
+ // -- lr : return address
+ // -- r0 : key
+ // -- r1 : receiver
+ // -----------------------------------
+ Label miss_force_generic, slow_allocate_heapnumber;
+
+ Register key_reg = r0;
+ Register receiver_reg = r1;
+ Register elements_reg = r2;
+ Register heap_number_reg = r2;
+
+ // This stub is meant to be tail-jumped to, the receiver must already
+ // have been verified by the caller to not be a smi.
+
+ // Check that the key is a smi.
+ __ JumpIfNotSmi(key_reg, &miss_force_generic);
+
+ // Get the elements array.
+ __ ldr(elements_reg,
+ FieldMemOperand(receiver_reg, JSObject::kElementsOffset));
+
+ // Check that the key is within bounds.
+ __ ldr(r3, FieldMemOperand(elements_reg, FixedArray::kLengthOffset));
Mads Ager (chromium) 2011/07/12 12:03:26 In the store stub you have named the scratch regis
danno 2011/07/13 08:59:52 Done.
+ __ cmp(key_reg, Operand(r3));
+ __ b(hs, &miss_force_generic);
+
+ // Load the upper word of the double in the fixed array and test for NaN.
+ __ add(r3, elements_reg,
+ Operand(key_reg, LSL, kDoubleSizeLog2 - kSmiTagSize));
+ uint32_t upper_32_offset = FixedArray::kHeaderSize + Register::kSizeInBytes;
Mads Ager (chromium) 2011/07/12 12:03:26 This doesn't really matter, but I like sizeof(kHol
danno 2011/07/13 08:59:52 Done.
+ __ ldr(r4, FieldMemOperand(r3, upper_32_offset));
+ // Detect the upper 32 bit pattern in the double that are a sentinel for the
+ // hole by detecting an overflow when adding 1.
+ ASSERT(0x7FFFFFFF == kHoleNanUpper32);
+ __ add(r5, r4, Operand(1), SetCC);
Rodolph Perfetta 2011/07/12 14:00:30 0x7FFFFFFF + 1 will not set the overflow flag, but
danno 2011/07/13 08:59:52 Done.
+ __ b(&miss_force_generic, vs);
+
+ // Non Nan. Allocate a new heap number and copy the double value into it.
Mads Ager (chromium) 2011/07/12 12:03:26 NaN
danno 2011/07/13 08:59:52 Done.
+ __ LoadRoot(r7, Heap::kHeapNumberMapRootIndex);
+ __ AllocateHeapNumber(heap_number_reg, r5, r6, r7, &slow_allocate_heapnumber);
+
+ // Don't need to reload the upper 32 bits of the double, it's already in r4.
+ __ str(r4, FieldMemOperand(heap_number_reg, HeapNumber::kExponentOffset));
+ __ ldr(r4, FieldMemOperand(r3, FixedArray::kHeaderSize));
+ __ str(r4, FieldMemOperand(heap_number_reg, HeapNumber::kMantissaOffset));
+
+ __ mov(r0, heap_number_reg);
+ __ Ret();
+
+ __ bind(&slow_allocate_heapnumber);
+ Handle<Code> slow_ic =
+ masm->isolate()->builtins()->KeyedLoadIC_Slow();
+ __ Jump(slow_ic, RelocInfo::CODE_TARGET);
+
+ __ bind(&miss_force_generic);
+ Handle<Code> miss_ic =
+ masm->isolate()->builtins()->KeyedLoadIC_MissForceGeneric();
+ __ Jump(miss_ic, RelocInfo::CODE_TARGET);
+}
+
+
void KeyedStoreStubCompiler::GenerateStoreFastElement(MacroAssembler* masm,
bool is_js_array) {
// ----------- S t a t e -------------
@@ -4231,6 +4295,116 @@ void KeyedStoreStubCompiler::GenerateStoreFastElement(MacroAssembler* masm,
}
+void KeyedStoreStubCompiler::GenerateStoreFastDoubleElement(
+ MacroAssembler* masm,
+ bool is_js_array) {
+ // ----------- S t a t e -------------
+ // -- r0 : value
+ // -- r1 : key
+ // -- r2 : receiver
+ // -- lr : return address
+ // -- r3 : scratch
+ // -- r4 : scratch
+ // -- r5 : scratch
+ // -----------------------------------
+ Label miss_force_generic, smi_value, is_nan, have_double_value;
+
+ Register value_reg = r0;
+ Register key_reg = r1;
+ Register receiver_reg = r2;
+ Register scratch = r3;
+ Register elements_reg = r4;
+ Register scratch2 = r5;
+ Register scratch3 = r6;
+ Register scratch4 = r7;
+
+ // This stub is meant to be tail-jumped to, the receiver must already
+ // have been verified by the caller to not be a smi.
+ __ JumpIfNotSmi(key_reg, &miss_force_generic);
+
+ __ ldr(elements_reg,
+ FieldMemOperand(receiver_reg, JSObject::kElementsOffset));
+
+ // Check that the key is within bounds.
+ if (is_js_array) {
+ __ ldr(scratch, FieldMemOperand(receiver_reg, JSArray::kLengthOffset));
+ } else {
+ __ ldr(scratch,
+ FieldMemOperand(elements_reg, FixedArray::kLengthOffset));
+ }
+ // Compare smis, unsigned compare catches both negative and out-of-bound
+ // indexes.
+ __ cmp(key_reg, scratch);
+ __ b(hs, &miss_force_generic);
+
+ // Handle smi values specially.
+ __ JumpIfSmi(value_reg, &smi_value);
+
+ // Ensure that the object is a heap number
+ __ CheckMap(value_reg,
+ scratch,
+ masm->isolate()->factory()->heap_number_map(),
+ &miss_force_generic,
+ DONT_DO_SMI_CHECK);
+
+ // Check for nan: all NaN values have a value greater (signed) than 0x7ff00000
+ // in the exponent.
+ __ mov(scratch, Operand(0x7ff00000));
+ __ ldr(scratch3, FieldMemOperand(value_reg, HeapNumber::kExponentOffset));
+ __ cmp(scratch3, scratch);
+ __ b(gt, &is_nan);
+
+ __ ldr(scratch2, FieldMemOperand(value_reg, HeapNumber::kMantissaOffset));
+
+ __ bind(&have_double_value);
+ // Double value to store in the double array is in scratch2 and scratch3.
+ __ add(scratch, elements_reg,
+ Operand(key_reg, LSL, kDoubleSizeLog2 - kSmiTagSize));
+ __ str(scratch2, FieldMemOperand(scratch, FixedDoubleArray::kHeaderSize));
+ uint32_t offset = FixedDoubleArray::kHeaderSize + Register::kSizeInBytes;
+ __ str(scratch3, FieldMemOperand(scratch, offset));
+ __ Ret();
+
+ __ bind(&is_nan);
+ __ mov(scratch2, Operand(kCanonicalNonHoleNanLower32));
+ __ mov(scratch3, Operand(kCanonicalNonHoleNanUpper32));
+ __ jmp(&have_double_value);
+
+ __ bind(&smi_value);
+ __ add(scratch, elements_reg,
+ Operand(FixedDoubleArray::kHeaderSize - kHeapObjectTag));
+ __ add(scratch, scratch,
+ Operand(key_reg, LSL, kDoubleSizeLog2 - kSmiTagSize));
+ // scratch is now effective address of the double element
+
+ FloatingPointHelper::Destination destination;
+ if (CpuFeatures::IsSupported(VFP3)) {
+ destination = FloatingPointHelper::kVFPRegisters;
+ } else {
+ destination = FloatingPointHelper::kCoreRegisters;
+ }
+ __ SmiUntag(value_reg, value_reg);
+ FloatingPointHelper::ConvertIntToDouble(
+ masm, value_reg, destination,
+ d0, scratch2, scratch3, // These are: double_dst, dst1, dst2.
+ scratch4, s2); // These are: scratch2, single_scratch.
+ if (destination == FloatingPointHelper::kVFPRegisters) {
+ CpuFeatures::Scope scope(VFP3);
+ __ vstr(d0, scratch, 0);
+ } else {
+ __ str(scratch2, MemOperand(scratch, 0));
+ __ str(scratch3, MemOperand(scratch, Register::kSizeInBytes));
+ }
+ __ Ret();
+
+ // Handle store cache miss, replacing the ic with the generic stub.
+ __ bind(&miss_force_generic);
+ Handle<Code> ic =
+ masm->isolate()->builtins()->KeyedStoreIC_MissForceGeneric();
+ __ Jump(ic, RelocInfo::CODE_TARGET);
+}
+
+
#undef __
} } // namespace v8::internal

Powered by Google App Engine
This is Rietveld 408576698