 Chromium Code Reviews
 Chromium Code Reviews Issue 7307030:
  Implement ICs for FastDoubleArray loads and stores  (Closed) 
  Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
    
  
    Issue 7307030:
  Implement ICs for FastDoubleArray loads and stores  (Closed) 
  Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge| OLD | NEW | 
|---|---|
| 1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 the V8 project authors. All rights reserved. | 
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without | 
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are | 
| 4 // met: | 4 // met: | 
| 5 // | 5 // | 
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright | 
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. | 
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above | 
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following | 
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided | 
| (...skipping 4150 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4161 __ mov(r0, r4); | 4161 __ mov(r0, r4); | 
| 4162 __ Ret(); | 4162 __ Ret(); | 
| 4163 | 4163 | 
| 4164 __ bind(&miss_force_generic); | 4164 __ bind(&miss_force_generic); | 
| 4165 Code* stub = masm->isolate()->builtins()->builtin( | 4165 Code* stub = masm->isolate()->builtins()->builtin( | 
| 4166 Builtins::kKeyedLoadIC_MissForceGeneric); | 4166 Builtins::kKeyedLoadIC_MissForceGeneric); | 
| 4167 __ Jump(Handle<Code>(stub), RelocInfo::CODE_TARGET); | 4167 __ Jump(Handle<Code>(stub), RelocInfo::CODE_TARGET); | 
| 4168 } | 4168 } | 
| 4169 | 4169 | 
| 4170 | 4170 | 
| 4171 void KeyedLoadStubCompiler::GenerateLoadFastDoubleElement( | |
| 4172 MacroAssembler* masm) { | |
| 4173 // ----------- S t a t e ------------- | |
| 4174 // -- lr : return address | |
| 4175 // -- r0 : key | |
| 4176 // -- r1 : receiver | |
| 4177 // ----------------------------------- | |
| 4178 Label miss_force_generic, slow_allocate_heapnumber; | |
| 4179 | |
| 4180 Register key_reg = r0; | |
| 4181 Register receiver_reg = r1; | |
| 4182 Register elements_reg = r2; | |
| 4183 Register heap_number_reg = r2; | |
| 4184 | |
| 4185 // This stub is meant to be tail-jumped to, the receiver must already | |
| 4186 // have been verified by the caller to not be a smi. | |
| 4187 | |
| 4188 // Check that the key is a smi. | |
| 4189 __ JumpIfNotSmi(key_reg, &miss_force_generic); | |
| 4190 | |
| 4191 // Get the elements array. | |
| 4192 __ ldr(elements_reg, | |
| 4193 FieldMemOperand(receiver_reg, JSObject::kElementsOffset)); | |
| 4194 | |
| 4195 // Check that the key is within bounds. | |
| 4196 __ 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.
 | |
| 4197 __ cmp(key_reg, Operand(r3)); | |
| 4198 __ b(hs, &miss_force_generic); | |
| 4199 | |
| 4200 // Load the upper word of the double in the fixed array and test for NaN. | |
| 4201 __ add(r3, elements_reg, | |
| 4202 Operand(key_reg, LSL, kDoubleSizeLog2 - kSmiTagSize)); | |
| 4203 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.
 | |
| 4204 __ ldr(r4, FieldMemOperand(r3, upper_32_offset)); | |
| 4205 // Detect the upper 32 bit pattern in the double that are a sentinel for the | |
| 4206 // hole by detecting an overflow when adding 1. | |
| 4207 ASSERT(0x7FFFFFFF == kHoleNanUpper32); | |
| 4208 __ 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.
 | |
| 4209 __ b(&miss_force_generic, vs); | |
| 4210 | |
| 4211 // 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.
 | |
| 4212 __ LoadRoot(r7, Heap::kHeapNumberMapRootIndex); | |
| 4213 __ AllocateHeapNumber(heap_number_reg, r5, r6, r7, &slow_allocate_heapnumber); | |
| 4214 | |
| 4215 // Don't need to reload the upper 32 bits of the double, it's already in r4. | |
| 4216 __ str(r4, FieldMemOperand(heap_number_reg, HeapNumber::kExponentOffset)); | |
| 4217 __ ldr(r4, FieldMemOperand(r3, FixedArray::kHeaderSize)); | |
| 4218 __ str(r4, FieldMemOperand(heap_number_reg, HeapNumber::kMantissaOffset)); | |
| 4219 | |
| 4220 __ mov(r0, heap_number_reg); | |
| 4221 __ Ret(); | |
| 4222 | |
| 4223 __ bind(&slow_allocate_heapnumber); | |
| 4224 Handle<Code> slow_ic = | |
| 4225 masm->isolate()->builtins()->KeyedLoadIC_Slow(); | |
| 4226 __ Jump(slow_ic, RelocInfo::CODE_TARGET); | |
| 4227 | |
| 4228 __ bind(&miss_force_generic); | |
| 4229 Handle<Code> miss_ic = | |
| 4230 masm->isolate()->builtins()->KeyedLoadIC_MissForceGeneric(); | |
| 4231 __ Jump(miss_ic, RelocInfo::CODE_TARGET); | |
| 4232 } | |
| 4233 | |
| 4234 | |
| 4171 void KeyedStoreStubCompiler::GenerateStoreFastElement(MacroAssembler* masm, | 4235 void KeyedStoreStubCompiler::GenerateStoreFastElement(MacroAssembler* masm, | 
| 4172 bool is_js_array) { | 4236 bool is_js_array) { | 
| 4173 // ----------- S t a t e ------------- | 4237 // ----------- S t a t e ------------- | 
| 4174 // -- r0 : value | 4238 // -- r0 : value | 
| 4175 // -- r1 : key | 4239 // -- r1 : key | 
| 4176 // -- r2 : receiver | 4240 // -- r2 : receiver | 
| 4177 // -- lr : return address | 4241 // -- lr : return address | 
| 4178 // -- r3 : scratch | 4242 // -- r3 : scratch | 
| 4179 // -- r4 : scratch (elements) | 4243 // -- r4 : scratch (elements) | 
| 4180 // ----------------------------------- | 4244 // ----------------------------------- | 
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4224 // Done. | 4288 // Done. | 
| 4225 __ Ret(); | 4289 __ Ret(); | 
| 4226 | 4290 | 
| 4227 __ bind(&miss_force_generic); | 4291 __ bind(&miss_force_generic); | 
| 4228 Handle<Code> ic = | 4292 Handle<Code> ic = | 
| 4229 masm->isolate()->builtins()->KeyedStoreIC_MissForceGeneric(); | 4293 masm->isolate()->builtins()->KeyedStoreIC_MissForceGeneric(); | 
| 4230 __ Jump(ic, RelocInfo::CODE_TARGET); | 4294 __ Jump(ic, RelocInfo::CODE_TARGET); | 
| 4231 } | 4295 } | 
| 4232 | 4296 | 
| 4233 | 4297 | 
| 4298 void KeyedStoreStubCompiler::GenerateStoreFastDoubleElement( | |
| 4299 MacroAssembler* masm, | |
| 4300 bool is_js_array) { | |
| 4301 // ----------- S t a t e ------------- | |
| 4302 // -- r0 : value | |
| 4303 // -- r1 : key | |
| 4304 // -- r2 : receiver | |
| 4305 // -- lr : return address | |
| 4306 // -- r3 : scratch | |
| 4307 // -- r4 : scratch | |
| 4308 // -- r5 : scratch | |
| 4309 // ----------------------------------- | |
| 4310 Label miss_force_generic, smi_value, is_nan, have_double_value; | |
| 4311 | |
| 4312 Register value_reg = r0; | |
| 4313 Register key_reg = r1; | |
| 4314 Register receiver_reg = r2; | |
| 4315 Register scratch = r3; | |
| 4316 Register elements_reg = r4; | |
| 4317 Register scratch2 = r5; | |
| 4318 Register scratch3 = r6; | |
| 4319 Register scratch4 = r7; | |
| 4320 | |
| 4321 // This stub is meant to be tail-jumped to, the receiver must already | |
| 4322 // have been verified by the caller to not be a smi. | |
| 4323 __ JumpIfNotSmi(key_reg, &miss_force_generic); | |
| 4324 | |
| 4325 __ ldr(elements_reg, | |
| 4326 FieldMemOperand(receiver_reg, JSObject::kElementsOffset)); | |
| 4327 | |
| 4328 // Check that the key is within bounds. | |
| 4329 if (is_js_array) { | |
| 4330 __ ldr(scratch, FieldMemOperand(receiver_reg, JSArray::kLengthOffset)); | |
| 4331 } else { | |
| 4332 __ ldr(scratch, | |
| 4333 FieldMemOperand(elements_reg, FixedArray::kLengthOffset)); | |
| 4334 } | |
| 4335 // Compare smis, unsigned compare catches both negative and out-of-bound | |
| 4336 // indexes. | |
| 4337 __ cmp(key_reg, scratch); | |
| 4338 __ b(hs, &miss_force_generic); | |
| 4339 | |
| 4340 // Handle smi values specially. | |
| 4341 __ JumpIfSmi(value_reg, &smi_value); | |
| 4342 | |
| 4343 // Ensure that the object is a heap number | |
| 4344 __ CheckMap(value_reg, | |
| 4345 scratch, | |
| 4346 masm->isolate()->factory()->heap_number_map(), | |
| 4347 &miss_force_generic, | |
| 4348 DONT_DO_SMI_CHECK); | |
| 4349 | |
| 4350 // Check for nan: all NaN values have a value greater (signed) than 0x7ff00000 | |
| 4351 // in the exponent. | |
| 4352 __ mov(scratch, Operand(0x7ff00000)); | |
| 4353 __ ldr(scratch3, FieldMemOperand(value_reg, HeapNumber::kExponentOffset)); | |
| 4354 __ cmp(scratch3, scratch); | |
| 4355 __ b(gt, &is_nan); | |
| 4356 | |
| 4357 __ ldr(scratch2, FieldMemOperand(value_reg, HeapNumber::kMantissaOffset)); | |
| 4358 | |
| 4359 __ bind(&have_double_value); | |
| 4360 // Double value to store in the double array is in scratch2 and scratch3. | |
| 4361 __ add(scratch, elements_reg, | |
| 4362 Operand(key_reg, LSL, kDoubleSizeLog2 - kSmiTagSize)); | |
| 4363 __ str(scratch2, FieldMemOperand(scratch, FixedDoubleArray::kHeaderSize)); | |
| 4364 uint32_t offset = FixedDoubleArray::kHeaderSize + Register::kSizeInBytes; | |
| 4365 __ str(scratch3, FieldMemOperand(scratch, offset)); | |
| 4366 __ Ret(); | |
| 4367 | |
| 4368 __ bind(&is_nan); | |
| 4369 __ mov(scratch2, Operand(kCanonicalNonHoleNanLower32)); | |
| 4370 __ mov(scratch3, Operand(kCanonicalNonHoleNanUpper32)); | |
| 4371 __ jmp(&have_double_value); | |
| 4372 | |
| 4373 __ bind(&smi_value); | |
| 4374 __ add(scratch, elements_reg, | |
| 4375 Operand(FixedDoubleArray::kHeaderSize - kHeapObjectTag)); | |
| 4376 __ add(scratch, scratch, | |
| 4377 Operand(key_reg, LSL, kDoubleSizeLog2 - kSmiTagSize)); | |
| 4378 // scratch is now effective address of the double element | |
| 4379 | |
| 4380 FloatingPointHelper::Destination destination; | |
| 4381 if (CpuFeatures::IsSupported(VFP3)) { | |
| 4382 destination = FloatingPointHelper::kVFPRegisters; | |
| 4383 } else { | |
| 4384 destination = FloatingPointHelper::kCoreRegisters; | |
| 4385 } | |
| 4386 __ SmiUntag(value_reg, value_reg); | |
| 4387 FloatingPointHelper::ConvertIntToDouble( | |
| 4388 masm, value_reg, destination, | |
| 4389 d0, scratch2, scratch3, // These are: double_dst, dst1, dst2. | |
| 4390 scratch4, s2); // These are: scratch2, single_scratch. | |
| 4391 if (destination == FloatingPointHelper::kVFPRegisters) { | |
| 4392 CpuFeatures::Scope scope(VFP3); | |
| 4393 __ vstr(d0, scratch, 0); | |
| 4394 } else { | |
| 4395 __ str(scratch2, MemOperand(scratch, 0)); | |
| 4396 __ str(scratch3, MemOperand(scratch, Register::kSizeInBytes)); | |
| 4397 } | |
| 4398 __ Ret(); | |
| 4399 | |
| 4400 // Handle store cache miss, replacing the ic with the generic stub. | |
| 4401 __ bind(&miss_force_generic); | |
| 4402 Handle<Code> ic = | |
| 4403 masm->isolate()->builtins()->KeyedStoreIC_MissForceGeneric(); | |
| 4404 __ Jump(ic, RelocInfo::CODE_TARGET); | |
| 4405 } | |
| 4406 | |
| 4407 | |
| 4234 #undef __ | 4408 #undef __ | 
| 4235 | 4409 | 
| 4236 } } // namespace v8::internal | 4410 } } // namespace v8::internal | 
| 4237 | 4411 | 
| 4238 #endif // V8_TARGET_ARCH_ARM | 4412 #endif // V8_TARGET_ARCH_ARM | 
| OLD | NEW |