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 |