| 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 6918 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6929 // Used in CompileStoreGlobal. | 6929 // Used in CompileStoreGlobal. |
| 6930 { r4, r1, r2, OMIT_REMEMBERED_SET }, | 6930 { r4, r1, r2, OMIT_REMEMBERED_SET }, |
| 6931 // Used in StoreStubCompiler::CompileStoreField via GenerateStoreField. | 6931 // Used in StoreStubCompiler::CompileStoreField via GenerateStoreField. |
| 6932 { r1, r2, r3, EMIT_REMEMBERED_SET }, | 6932 { r1, r2, r3, EMIT_REMEMBERED_SET }, |
| 6933 { r3, r2, r1, EMIT_REMEMBERED_SET }, | 6933 { r3, r2, r1, EMIT_REMEMBERED_SET }, |
| 6934 // Used in KeyedStoreStubCompiler::CompileStoreField via GenerateStoreField. | 6934 // Used in KeyedStoreStubCompiler::CompileStoreField via GenerateStoreField. |
| 6935 { r2, r1, r3, EMIT_REMEMBERED_SET }, | 6935 { r2, r1, r3, EMIT_REMEMBERED_SET }, |
| 6936 { r3, r1, r2, EMIT_REMEMBERED_SET }, | 6936 { r3, r1, r2, EMIT_REMEMBERED_SET }, |
| 6937 // KeyedStoreStubCompiler::GenerateStoreFastElement. | 6937 // KeyedStoreStubCompiler::GenerateStoreFastElement. |
| 6938 { r4, r2, r3, EMIT_REMEMBERED_SET }, | 6938 { r4, r2, r3, EMIT_REMEMBERED_SET }, |
| 6939 // FastElementsConversionStub::GenerateSmiOnlyToObject | 6939 // ElementsTransitionGenerator::GenerateSmiOnlyToObject |
| 6940 // and FastElementsConversionStub::GenerateSmiOnlyToDouble | 6940 // and ElementsTransitionGenerator::GenerateSmiOnlyToDouble |
| 6941 // and FastElementsConversionStub::GenerateDoubleToObject | 6941 // and ElementsTransitionGenerator::GenerateDoubleToObject |
| 6942 { r2, r3, r9, EMIT_REMEMBERED_SET }, | 6942 { r2, r3, r9, EMIT_REMEMBERED_SET }, |
| 6943 // FastElementsConversionStub::GenerateDoubleToObject | 6943 // ElementsTransitionGenerator::GenerateDoubleToObject |
| 6944 { r6, r2, r0, EMIT_REMEMBERED_SET }, | 6944 { r6, r2, r0, EMIT_REMEMBERED_SET }, |
| 6945 { r2, r6, r9, EMIT_REMEMBERED_SET }, | 6945 { r2, r6, r9, EMIT_REMEMBERED_SET }, |
| 6946 // Null termination. | 6946 // Null termination. |
| 6947 { no_reg, no_reg, no_reg, EMIT_REMEMBERED_SET} | 6947 { no_reg, no_reg, no_reg, EMIT_REMEMBERED_SET} |
| 6948 }; | 6948 }; |
| 6949 | 6949 |
| 6950 | 6950 |
| 6951 bool RecordWriteStub::IsPregenerated() { | 6951 bool RecordWriteStub::IsPregenerated() { |
| 6952 for (AheadOfTimeWriteBarrierStubList* entry = kAheadOfTime; | 6952 for (AheadOfTimeWriteBarrierStubList* entry = kAheadOfTime; |
| 6953 !entry->object.is(no_reg); | 6953 !entry->object.is(no_reg); |
| (...skipping 218 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7172 } | 7172 } |
| 7173 | 7173 |
| 7174 __ bind(&need_incremental_pop_scratch); | 7174 __ bind(&need_incremental_pop_scratch); |
| 7175 __ Pop(regs_.object(), regs_.address()); | 7175 __ Pop(regs_.object(), regs_.address()); |
| 7176 | 7176 |
| 7177 __ bind(&need_incremental); | 7177 __ bind(&need_incremental); |
| 7178 | 7178 |
| 7179 // Fall through when we need to inform the incremental marker. | 7179 // Fall through when we need to inform the incremental marker. |
| 7180 } | 7180 } |
| 7181 | 7181 |
| 7182 | |
| 7183 void FastElementsConversionStub::GenerateSmiOnlyToObject( | |
| 7184 MacroAssembler* masm, | |
| 7185 StrictModeFlag strict_mode) { | |
| 7186 // ----------- S t a t e ------------- | |
| 7187 // -- r0 : value | |
| 7188 // -- r1 : key | |
| 7189 // -- r2 : receiver | |
| 7190 // -- lr : return address | |
| 7191 // -- r3 : target map, scratch for subsequent call | |
| 7192 // -- r4 : scratch (elements) | |
| 7193 // ----------------------------------- | |
| 7194 // Set transitioned map. | |
| 7195 __ str(r3, FieldMemOperand(r2, HeapObject::kMapOffset)); | |
| 7196 __ RecordWriteField(r2, | |
| 7197 HeapObject::kMapOffset, | |
| 7198 r3, | |
| 7199 r9, | |
| 7200 kLRHasNotBeenSaved, | |
| 7201 kDontSaveFPRegs, | |
| 7202 EMIT_REMEMBERED_SET, | |
| 7203 OMIT_SMI_CHECK); | |
| 7204 } | |
| 7205 | |
| 7206 | |
| 7207 void FastElementsConversionStub::GenerateSmiOnlyToDouble( | |
| 7208 MacroAssembler* masm, StrictModeFlag strict_mode) { | |
| 7209 // ----------- S t a t e ------------- | |
| 7210 // -- r0 : value | |
| 7211 // -- r1 : key | |
| 7212 // -- r2 : receiver | |
| 7213 // -- lr : return address | |
| 7214 // -- r3 : target map, scratch for subsequent call | |
| 7215 // -- r4 : scratch (elements) | |
| 7216 // ----------------------------------- | |
| 7217 Label loop, entry, convert_hole, gc_required, fail; | |
| 7218 bool vfp3_supported = CpuFeatures::IsSupported(VFP3); | |
| 7219 | |
| 7220 __ ldr(r4, FieldMemOperand(r2, JSObject::kElementsOffset)); | |
| 7221 __ ldr(r5, FieldMemOperand(r4, FixedArray::kLengthOffset)); | |
| 7222 // r4: source FixedArray | |
| 7223 // r5: number of elements (smi-tagged) | |
| 7224 | |
| 7225 // Allocate new FixedDoubleArray. | |
| 7226 __ mov(ip, Operand(FixedDoubleArray::kHeaderSize)); | |
| 7227 __ add(ip, ip, Operand(r5, LSL, 2)); | |
| 7228 __ AllocateInNewSpace(ip, r6, r7, r9, &gc_required, NO_ALLOCATION_FLAGS); | |
| 7229 // r6: destination FixedDoubleArray, not tagged as heap object | |
| 7230 __ LoadRoot(r9, Heap::kFixedDoubleArrayMapRootIndex); | |
| 7231 __ str(r9, MemOperand(r6, HeapObject::kMapOffset)); | |
| 7232 // Set destination FixedDoubleArray's length. | |
| 7233 __ str(r5, MemOperand(r6, FixedDoubleArray::kLengthOffset)); | |
| 7234 // Update receiver's map. | |
| 7235 __ push(lr); | |
| 7236 __ str(r3, FieldMemOperand(r2, HeapObject::kMapOffset)); | |
| 7237 __ RecordWriteField(r2, | |
| 7238 HeapObject::kMapOffset, | |
| 7239 r3, | |
| 7240 r9, | |
| 7241 kLRHasBeenSaved, | |
| 7242 kDontSaveFPRegs, | |
| 7243 EMIT_REMEMBERED_SET, | |
| 7244 OMIT_SMI_CHECK); | |
| 7245 // Replace receiver's backing store with newly created FixedDoubleArray. | |
| 7246 __ add(r3, r6, Operand(kHeapObjectTag)); | |
| 7247 __ str(r3, FieldMemOperand(r2, JSObject::kElementsOffset)); | |
| 7248 __ RecordWriteField(r2, | |
| 7249 JSObject::kElementsOffset, | |
| 7250 r3, | |
| 7251 r9, | |
| 7252 kLRHasBeenSaved, | |
| 7253 kDontSaveFPRegs, | |
| 7254 EMIT_REMEMBERED_SET, | |
| 7255 OMIT_SMI_CHECK); | |
| 7256 __ pop(lr); | |
| 7257 | |
| 7258 // Prepare for conversion loop. | |
| 7259 __ add(r3, r4, Operand(FixedArray::kHeaderSize - kHeapObjectTag)); | |
| 7260 __ add(r7, r6, Operand(FixedDoubleArray::kHeaderSize)); | |
| 7261 __ add(r6, r7, Operand(r5, LSL, 2)); | |
| 7262 __ mov(r4, Operand(kHoleNanLower32)); | |
| 7263 __ mov(r5, Operand(kHoleNanUpper32)); | |
| 7264 // r3: begin of source FixedArray element fields, not tagged | |
| 7265 // r4: kHoleNanLower32 | |
| 7266 // r5: kHoleNanUpper32 | |
| 7267 // r6: end of destination FixedDoubleArray, not tagged | |
| 7268 // r7: begin of FixedDoubleArray element fields, not tagged | |
| 7269 if (vfp3_supported) __ Push(r1, r0); | |
| 7270 | |
| 7271 __ b(&entry); | |
| 7272 | |
| 7273 // Call into runtime if GC is required. | |
| 7274 __ bind(&gc_required); | |
| 7275 KeyedStoreIC::GenerateRuntimeSetProperty(masm, strict_mode); | |
| 7276 | |
| 7277 // Convert and copy elements. | |
| 7278 __ bind(&loop); | |
| 7279 __ ldr(r9, MemOperand(r3, 4, PostIndex)); | |
| 7280 // r9: current element | |
| 7281 __ JumpIfNotSmi(r9, &convert_hole); | |
| 7282 | |
| 7283 // Normal smi, convert to double and store. | |
| 7284 __ SmiUntag(r9); | |
| 7285 if (vfp3_supported) { | |
| 7286 CpuFeatures::Scope scope(VFP3); | |
| 7287 __ vmov(s0, r9); | |
| 7288 __ vcvt_f64_s32(d0, s0); | |
| 7289 __ vstr(d0, r7, 0); | |
| 7290 __ add(r7, r7, Operand(8)); | |
| 7291 } else { | |
| 7292 FloatingPointHelper::ConvertIntToDouble(masm, | |
| 7293 r9, | |
| 7294 FloatingPointHelper::kCoreRegisters, | |
| 7295 d0, | |
| 7296 r0, | |
| 7297 r1, | |
| 7298 ip, | |
| 7299 s0); | |
| 7300 __ Strd(r0, r1, MemOperand(r7, 8, PostIndex)); | |
| 7301 } | |
| 7302 __ b(&entry); | |
| 7303 | |
| 7304 // Hole found, store the-hole NaN. | |
| 7305 __ bind(&convert_hole); | |
| 7306 __ Strd(r4, r5, MemOperand(r7, 8, PostIndex)); | |
| 7307 | |
| 7308 __ bind(&entry); | |
| 7309 __ cmp(r7, r6); | |
| 7310 __ b(lt, &loop); | |
| 7311 | |
| 7312 if (vfp3_supported) __ Pop(r1, r0); | |
| 7313 } | |
| 7314 | |
| 7315 | |
| 7316 void FastElementsConversionStub::GenerateDoubleToObject( | |
| 7317 MacroAssembler* masm, StrictModeFlag strict_mode) { | |
| 7318 // ----------- S t a t e ------------- | |
| 7319 // -- r0 : value | |
| 7320 // -- r1 : key | |
| 7321 // -- r2 : receiver | |
| 7322 // -- lr : return address | |
| 7323 // -- r3 : target map, scratch for subsequent call | |
| 7324 // -- r4 : scratch (elements) | |
| 7325 // ----------------------------------- | |
| 7326 Label entry, loop, convert_hole, gc_required; | |
| 7327 | |
| 7328 __ push(lr); | |
| 7329 __ Push(r3, r2, r1, r0); | |
| 7330 | |
| 7331 __ ldr(r4, FieldMemOperand(r2, JSObject::kElementsOffset)); | |
| 7332 __ ldr(r5, FieldMemOperand(r4, FixedArray::kLengthOffset)); | |
| 7333 // r4: source FixedDoubleArray | |
| 7334 // r5: number of elements (smi-tagged) | |
| 7335 | |
| 7336 // Allocate new FixedArray. | |
| 7337 __ mov(r0, Operand(FixedDoubleArray::kHeaderSize)); | |
| 7338 __ add(r0, r0, Operand(r5, LSL, 1)); | |
| 7339 __ AllocateInNewSpace(r0, r6, r7, r9, &gc_required, NO_ALLOCATION_FLAGS); | |
| 7340 // r6: destination FixedArray, not tagged as heap object | |
| 7341 __ LoadRoot(r9, Heap::kFixedArrayMapRootIndex); | |
| 7342 __ str(r9, MemOperand(r6, HeapObject::kMapOffset)); | |
| 7343 // Set destination FixedDoubleArray's length. | |
| 7344 __ str(r5, MemOperand(r6, FixedDoubleArray::kLengthOffset)); | |
| 7345 | |
| 7346 // Prepare for conversion loop. | |
| 7347 __ add(r4, r4, Operand(FixedDoubleArray::kHeaderSize - kHeapObjectTag + 4)); | |
| 7348 __ add(r3, r6, Operand(FixedArray::kHeaderSize)); | |
| 7349 __ add(r6, r6, Operand(kHeapObjectTag)); | |
| 7350 __ add(r5, r3, Operand(r5, LSL, 1)); | |
| 7351 __ LoadRoot(r7, Heap::kTheHoleValueRootIndex); | |
| 7352 __ LoadRoot(r9, Heap::kHeapNumberMapRootIndex); | |
| 7353 // Using offsetted addresses in r4 to fully take advantage of post-indexing. | |
| 7354 // r3: begin of destination FixedArray element fields, not tagged | |
| 7355 // r4: begin of source FixedDoubleArray element fields, not tagged, +4 | |
| 7356 // r5: end of destination FixedArray, not tagged | |
| 7357 // r6: destination FixedArray | |
| 7358 // r7: the-hole pointer | |
| 7359 // r9: heap number map | |
| 7360 __ b(&entry); | |
| 7361 | |
| 7362 // Call into runtime if GC is required. | |
| 7363 __ bind(&gc_required); | |
| 7364 __ Pop(r3, r2, r1, r0); | |
| 7365 __ pop(lr); | |
| 7366 KeyedStoreIC::GenerateRuntimeSetProperty(masm, strict_mode); | |
| 7367 | |
| 7368 __ bind(&loop); | |
| 7369 __ ldr(r1, MemOperand(r4, 8, PostIndex)); | |
| 7370 // lr: current element's upper 32 bit | |
| 7371 // r4: address of next element's upper 32 bit | |
| 7372 __ cmp(r1, Operand(kHoleNanUpper32)); | |
| 7373 __ b(eq, &convert_hole); | |
| 7374 | |
| 7375 // Non-hole double, copy value into a heap number. | |
| 7376 __ AllocateHeapNumber(r2, r0, lr, r9, &gc_required); | |
| 7377 // r2: new heap number | |
| 7378 __ ldr(r0, MemOperand(r4, 12, NegOffset)); | |
| 7379 __ Strd(r0, r1, FieldMemOperand(r2, HeapNumber::kValueOffset)); | |
| 7380 __ mov(r0, r3); | |
| 7381 __ str(r2, MemOperand(r3, 4, PostIndex)); | |
| 7382 __ RecordWrite(r6, | |
| 7383 r0, | |
| 7384 r2, | |
| 7385 kLRHasBeenSaved, | |
| 7386 kDontSaveFPRegs, | |
| 7387 EMIT_REMEMBERED_SET, | |
| 7388 OMIT_SMI_CHECK); | |
| 7389 __ b(&entry); | |
| 7390 | |
| 7391 // Replace the-hole NaN with the-hole pointer. | |
| 7392 __ bind(&convert_hole); | |
| 7393 __ str(r7, MemOperand(r3, 4, PostIndex)); | |
| 7394 | |
| 7395 __ bind(&entry); | |
| 7396 __ cmp(r3, r5); | |
| 7397 __ b(lt, &loop); | |
| 7398 | |
| 7399 __ Pop(r3, r2, r1, r0); | |
| 7400 // Update receiver's map. | |
| 7401 __ str(r3, FieldMemOperand(r2, HeapObject::kMapOffset)); | |
| 7402 __ RecordWriteField(r2, | |
| 7403 HeapObject::kMapOffset, | |
| 7404 r3, | |
| 7405 r9, | |
| 7406 kLRHasBeenSaved, | |
| 7407 kDontSaveFPRegs, | |
| 7408 EMIT_REMEMBERED_SET, | |
| 7409 OMIT_SMI_CHECK); | |
| 7410 // Replace receiver's backing store with newly created and filled FixedArray. | |
| 7411 __ str(r6, FieldMemOperand(r2, JSObject::kElementsOffset)); | |
| 7412 __ RecordWriteField(r2, | |
| 7413 JSObject::kElementsOffset, | |
| 7414 r6, | |
| 7415 r9, | |
| 7416 kLRHasBeenSaved, | |
| 7417 kDontSaveFPRegs, | |
| 7418 EMIT_REMEMBERED_SET, | |
| 7419 OMIT_SMI_CHECK); | |
| 7420 __ pop(lr); | |
| 7421 } | |
| 7422 | |
| 7423 | |
| 7424 #undef __ | 7182 #undef __ |
| 7425 | 7183 |
| 7426 } } // namespace v8::internal | 7184 } } // namespace v8::internal |
| 7427 | 7185 |
| 7428 #endif // V8_TARGET_ARCH_ARM | 7186 #endif // V8_TARGET_ARCH_ARM |
| OLD | NEW |