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