OLD | NEW |
1 // Copyright 2006-2009 the V8 project authors. All rights reserved. | 1 // Copyright 2006-2009 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 292 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
303 | 303 |
304 | 304 |
305 void MacroAssembler::StoreRoot(Register source, | 305 void MacroAssembler::StoreRoot(Register source, |
306 Heap::RootListIndex index, | 306 Heap::RootListIndex index, |
307 Condition cond) { | 307 Condition cond) { |
308 str(source, MemOperand(roots, index << kPointerSizeLog2), cond); | 308 str(source, MemOperand(roots, index << kPointerSizeLog2), cond); |
309 } | 309 } |
310 | 310 |
311 | 311 |
312 void MacroAssembler::RecordWriteHelper(Register object, | 312 void MacroAssembler::RecordWriteHelper(Register object, |
313 Operand offset, | 313 Register address, |
314 Register scratch0, | 314 Register scratch) { |
315 Register scratch1) { | |
316 if (FLAG_debug_code) { | 315 if (FLAG_debug_code) { |
317 // Check that the object is not in new space. | 316 // Check that the object is not in new space. |
318 Label not_in_new_space; | 317 Label not_in_new_space; |
319 InNewSpace(object, scratch1, ne, ¬_in_new_space); | 318 InNewSpace(object, scratch, ne, ¬_in_new_space); |
320 Abort("new-space object passed to RecordWriteHelper"); | 319 Abort("new-space object passed to RecordWriteHelper"); |
321 bind(¬_in_new_space); | 320 bind(¬_in_new_space); |
322 } | 321 } |
323 | 322 |
324 // Add offset into the object. | |
325 add(scratch0, object, offset); | |
326 | |
327 // Calculate page address. | 323 // Calculate page address. |
328 Bfc(object, 0, kPageSizeBits); | 324 Bfc(object, 0, kPageSizeBits); |
329 | 325 |
330 // Calculate region number. | 326 // Calculate region number. |
331 Ubfx(scratch0, scratch0, Page::kRegionSizeLog2, | 327 Ubfx(address, address, Page::kRegionSizeLog2, |
332 kPageSizeBits - Page::kRegionSizeLog2); | 328 kPageSizeBits - Page::kRegionSizeLog2); |
333 | 329 |
334 // Mark region dirty. | 330 // Mark region dirty. |
335 ldr(scratch1, MemOperand(object, Page::kDirtyFlagOffset)); | 331 ldr(scratch, MemOperand(object, Page::kDirtyFlagOffset)); |
336 mov(ip, Operand(1)); | 332 mov(ip, Operand(1)); |
337 orr(scratch1, scratch1, Operand(ip, LSL, scratch0)); | 333 orr(scratch, scratch, Operand(ip, LSL, address)); |
338 str(scratch1, MemOperand(object, Page::kDirtyFlagOffset)); | 334 str(scratch, MemOperand(object, Page::kDirtyFlagOffset)); |
339 } | 335 } |
340 | 336 |
341 | 337 |
342 void MacroAssembler::InNewSpace(Register object, | 338 void MacroAssembler::InNewSpace(Register object, |
343 Register scratch, | 339 Register scratch, |
344 Condition cc, | 340 Condition cc, |
345 Label* branch) { | 341 Label* branch) { |
346 ASSERT(cc == eq || cc == ne); | 342 ASSERT(cc == eq || cc == ne); |
347 and_(scratch, object, Operand(ExternalReference::new_space_mask())); | 343 and_(scratch, object, Operand(ExternalReference::new_space_mask())); |
348 cmp(scratch, Operand(ExternalReference::new_space_start())); | 344 cmp(scratch, Operand(ExternalReference::new_space_start())); |
(...skipping 12 matching lines...) Expand all Loading... |
361 // context register, so we check that none of the clobbered | 357 // context register, so we check that none of the clobbered |
362 // registers are cp. | 358 // registers are cp. |
363 ASSERT(!object.is(cp) && !scratch0.is(cp) && !scratch1.is(cp)); | 359 ASSERT(!object.is(cp) && !scratch0.is(cp) && !scratch1.is(cp)); |
364 | 360 |
365 Label done; | 361 Label done; |
366 | 362 |
367 // First, test that the object is not in the new space. We cannot set | 363 // First, test that the object is not in the new space. We cannot set |
368 // region marks for new space pages. | 364 // region marks for new space pages. |
369 InNewSpace(object, scratch0, eq, &done); | 365 InNewSpace(object, scratch0, eq, &done); |
370 | 366 |
| 367 // Add offset into the object. |
| 368 add(scratch0, object, offset); |
| 369 |
371 // Record the actual write. | 370 // Record the actual write. |
372 RecordWriteHelper(object, offset, scratch0, scratch1); | 371 RecordWriteHelper(object, scratch0, scratch1); |
373 | 372 |
374 bind(&done); | 373 bind(&done); |
375 | 374 |
376 // Clobber all input registers when running with the debug-code flag | 375 // Clobber all input registers when running with the debug-code flag |
377 // turned on to provoke errors. | 376 // turned on to provoke errors. |
378 if (FLAG_debug_code) { | 377 if (FLAG_debug_code) { |
379 mov(object, Operand(BitCast<int32_t>(kZapValue))); | 378 mov(object, Operand(BitCast<int32_t>(kZapValue))); |
380 mov(scratch0, Operand(BitCast<int32_t>(kZapValue))); | 379 mov(scratch0, Operand(BitCast<int32_t>(kZapValue))); |
381 mov(scratch1, Operand(BitCast<int32_t>(kZapValue))); | 380 mov(scratch1, Operand(BitCast<int32_t>(kZapValue))); |
382 } | 381 } |
383 } | 382 } |
384 | 383 |
385 | 384 |
| 385 // Will clobber 4 registers: object, address, scratch, ip. The |
| 386 // register 'object' contains a heap object pointer. The heap object |
| 387 // tag is shifted away. |
| 388 void MacroAssembler::RecordWrite(Register object, |
| 389 Register address, |
| 390 Register scratch) { |
| 391 // The compiled code assumes that record write doesn't change the |
| 392 // context register, so we check that none of the clobbered |
| 393 // registers are cp. |
| 394 ASSERT(!object.is(cp) && !address.is(cp) && !scratch.is(cp)); |
| 395 |
| 396 Label done; |
| 397 |
| 398 // First, test that the object is not in the new space. We cannot set |
| 399 // region marks for new space pages. |
| 400 InNewSpace(object, scratch, eq, &done); |
| 401 |
| 402 // Record the actual write. |
| 403 RecordWriteHelper(object, address, scratch); |
| 404 |
| 405 bind(&done); |
| 406 |
| 407 // Clobber all input registers when running with the debug-code flag |
| 408 // turned on to provoke errors. |
| 409 if (FLAG_debug_code) { |
| 410 mov(object, Operand(BitCast<int32_t>(kZapValue))); |
| 411 mov(address, Operand(BitCast<int32_t>(kZapValue))); |
| 412 mov(scratch, Operand(BitCast<int32_t>(kZapValue))); |
| 413 } |
| 414 } |
| 415 |
| 416 |
386 void MacroAssembler::Ldrd(Register dst1, Register dst2, | 417 void MacroAssembler::Ldrd(Register dst1, Register dst2, |
387 const MemOperand& src, Condition cond) { | 418 const MemOperand& src, Condition cond) { |
388 ASSERT(src.rm().is(no_reg)); | 419 ASSERT(src.rm().is(no_reg)); |
389 ASSERT(!dst1.is(lr)); // r14. | 420 ASSERT(!dst1.is(lr)); // r14. |
390 ASSERT_EQ(0, dst1.code() % 2); | 421 ASSERT_EQ(0, dst1.code() % 2); |
391 ASSERT_EQ(dst1.code() + 1, dst2.code()); | 422 ASSERT_EQ(dst1.code() + 1, dst2.code()); |
392 | 423 |
393 // Generate two ldr instructions if ldrd is not available. | 424 // Generate two ldr instructions if ldrd is not available. |
394 if (CpuFeatures::IsSupported(ARMv7)) { | 425 if (CpuFeatures::IsSupported(ARMv7)) { |
395 CpuFeatures::Scope scope(ARMv7); | 426 CpuFeatures::Scope scope(ARMv7); |
(...skipping 1507 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1903 | 1934 |
1904 void CodePatcher::Emit(Address addr) { | 1935 void CodePatcher::Emit(Address addr) { |
1905 masm()->emit(reinterpret_cast<Instr>(addr)); | 1936 masm()->emit(reinterpret_cast<Instr>(addr)); |
1906 } | 1937 } |
1907 #endif // ENABLE_DEBUGGER_SUPPORT | 1938 #endif // ENABLE_DEBUGGER_SUPPORT |
1908 | 1939 |
1909 | 1940 |
1910 } } // namespace v8::internal | 1941 } } // namespace v8::internal |
1911 | 1942 |
1912 #endif // V8_TARGET_ARCH_ARM | 1943 #endif // V8_TARGET_ARCH_ARM |
OLD | NEW |