Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(93)

Side by Side Diff: src/arm/code-stubs-arm.h

Issue 7605026: ARM: Support record write stubs for incremental marking. (Closed) Base URL: https://v8.googlecode.com/svn/branches/experimental/gc
Patch Set: Fix missing untagging in RecordWriteField. Created 9 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/arm/assembler-arm.h ('k') | src/arm/code-stubs-arm.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 391 matching lines...) Expand 10 before | Expand all | Expand 10 after
402 address, // An input reg. 402 address, // An input reg.
403 value) { // One scratch reg. 403 value) { // One scratch reg.
404 } 404 }
405 405
406 enum Mode { 406 enum Mode {
407 STORE_BUFFER_ONLY, 407 STORE_BUFFER_ONLY,
408 INCREMENTAL, 408 INCREMENTAL,
409 INCREMENTAL_COMPACTION 409 INCREMENTAL_COMPACTION
410 }; 410 };
411 411
412 static void PatchBranchIntoNop(MacroAssembler* masm, int pos) {
413 masm->instr_at_put(pos, (masm->instr_at(pos) & ~(B27 | B25)) |
Erik Corry 2011/08/11 07:35:21 You don't need to both zero out B25 and then set i
Michael Starzinger 2011/08/11 07:48:17 Done.
414 (B25 | B24 | B20));
415 ASSERT(Assembler::IsTstImmediate(masm->instr_at(pos)));
416 }
417
418 static void PatchNopIntoBranch(MacroAssembler* masm, int pos) {
419 masm->instr_at_put(pos, (masm->instr_at(pos) & ~(B25 | B24 | B20)) |
420 (B27 | B25));
421 ASSERT(Assembler::IsBranch(masm->instr_at(pos)));
422 }
423
412 static Mode GetMode(Code* stub) { 424 static Mode GetMode(Code* stub) {
425 Instr first_instruction = Assembler::instr_at(stub->instruction_start());
426 Instr second_instruction = Assembler::instr_at(stub->instruction_start() +
427 Assembler::kInstrSize);
428
429 if (Assembler::IsBranch(first_instruction)) {
430 return INCREMENTAL;
431 }
432
433 ASSERT(Assembler::IsTstImmediate(first_instruction));
434
435 if (Assembler::IsBranch(second_instruction)) {
436 return INCREMENTAL_COMPACTION;
437 }
438
439 ASSERT(Assembler::IsTstImmediate(second_instruction));
440
413 return STORE_BUFFER_ONLY; 441 return STORE_BUFFER_ONLY;
414 } 442 }
415 443
416 static void Patch(Code* stub, Mode mode) { 444 static void Patch(Code* stub, Mode mode) {
417 ASSERT(mode == STORE_BUFFER_ONLY); 445 MacroAssembler masm(NULL,
446 stub->instruction_start(),
447 stub->instruction_size());
448 switch (mode) {
449 case STORE_BUFFER_ONLY:
450 ASSERT(GetMode(stub) == INCREMENTAL ||
451 GetMode(stub) == INCREMENTAL_COMPACTION);
452 PatchBranchIntoNop(&masm, 0);
453 PatchBranchIntoNop(&masm, Assembler::kInstrSize);
454 break;
455 case INCREMENTAL:
456 ASSERT(GetMode(stub) == STORE_BUFFER_ONLY);
457 PatchNopIntoBranch(&masm, 0);
458 break;
459 case INCREMENTAL_COMPACTION:
460 ASSERT(GetMode(stub) == STORE_BUFFER_ONLY);
461 PatchNopIntoBranch(&masm, Assembler::kInstrSize);
462 break;
463 }
464 ASSERT(GetMode(stub) == mode);
465 CPU::FlushICache(stub->instruction_start(), 2 * Assembler::kInstrSize);
418 } 466 }
419 467
420 private: 468 private:
421 // This is a helper class for freeing up 3 scratch registers. The input is 469 // This is a helper class for freeing up 3 scratch registers. The input is
422 // two registers that must be preserved and one scratch register provided by 470 // two registers that must be preserved and one scratch register provided by
423 // the caller. 471 // the caller.
424 class RegisterAllocation { 472 class RegisterAllocation {
425 public: 473 public:
426 RegisterAllocation(Register object, 474 RegisterAllocation(Register object,
427 Register address, 475 Register address,
428 Register scratch0) 476 Register scratch0)
429 : object_(object), 477 : object_(object),
430 address_(address), 478 address_(address),
431 scratch0_(scratch0) { 479 scratch0_(scratch0) {
480 ASSERT(!AreAliased(scratch0, object, address, no_reg));
481 scratch1_ = GetRegThatIsNotOneOf(object_, address_, scratch0_);
432 } 482 }
483
484 void Save(MacroAssembler* masm) {
485 ASSERT(!AreAliased(object_, address_, scratch1_, scratch0_));
486 // We don't have to save scratch0_ because it was given to us as
487 // a scratch register.
488 masm->push(scratch1_);
489 }
490
491 void Restore(MacroAssembler* masm) {
492 masm->pop(scratch1_);
493 }
494
495 // If we have to call into C then we need to save and restore all caller-
496 // saved registers that were not already preserved. The scratch registers
497 // will be restored by other means so we don't bother pushing them here.
433 void SaveCallerSaveRegisters(MacroAssembler* masm, SaveFPRegsMode mode) { 498 void SaveCallerSaveRegisters(MacroAssembler* masm, SaveFPRegsMode mode) {
434 UNREACHABLE(); // TODO(gc): Save the caller save registers. 499 masm->stm(db_w, sp, (kCallerSaved | lr.bit()) & ~scratch1_.bit());
435 if (mode == kSaveFPRegs) { 500 if (mode == kSaveFPRegs) {
436 CpuFeatures::Scope scope(SSE2); 501 CpuFeatures::Scope scope(VFP3);
437 masm->sub(sp, 502 masm->sub(sp,
438 sp, 503 sp,
439 Operand(kDoubleSize * (DwVfpRegister::kNumRegisters - 1))); 504 Operand(kDoubleSize * (DwVfpRegister::kNumRegisters - 1)));
440 // Save all VFP registers except d0. 505 // Save all VFP registers except d0.
441 for (int i = DwVfpRegister::kNumRegisters - 1; i > 0; i--) { 506 for (int i = DwVfpRegister::kNumRegisters - 1; i > 0; i--) {
442 DwVfpRegister reg = DwVfpRegister::from_code(i); 507 DwVfpRegister reg = DwVfpRegister::from_code(i);
443 masm->vstr(reg, MemOperand(sp, (i - 1) * kDoubleSize)); 508 masm->vstr(reg, MemOperand(sp, (i - 1) * kDoubleSize));
444 } 509 }
445 } 510 }
446 } 511 }
447 512
448 inline void RestoreCallerSaveRegisters(MacroAssembler*masm, 513 inline void RestoreCallerSaveRegisters(MacroAssembler*masm,
449 SaveFPRegsMode mode) { 514 SaveFPRegsMode mode) {
450 if (mode == kSaveFPRegs) { 515 if (mode == kSaveFPRegs) {
451 CpuFeatures::Scope scope(SSE2); 516 CpuFeatures::Scope scope(VFP3);
452 // Restore all VFP registers except d0. 517 // Restore all VFP registers except d0.
453 for (int i = DwVfpRegister::kNumRegisters - 1; i > 0; i--) { 518 for (int i = DwVfpRegister::kNumRegisters - 1; i > 0; i--) {
454 DwVfpRegister reg = DwVfpRegister::from_code(i); 519 DwVfpRegister reg = DwVfpRegister::from_code(i);
455 masm->vldr(reg, MemOperand(sp, (i - 1) * kDoubleSize)); 520 masm->vldr(reg, MemOperand(sp, (i - 1) * kDoubleSize));
456 } 521 }
457 masm->add(sp, 522 masm->add(sp,
458 sp, 523 sp,
459 Operand(kDoubleSize * (DwVfpRegister::kNumRegisters - 1))); 524 Operand(kDoubleSize * (DwVfpRegister::kNumRegisters - 1)));
460 } 525 }
461 UNREACHABLE(); // TODO(gc): Restore the caller save registers. 526 masm->ldm(ia_w, sp, (kCallerSaved | lr.bit()) & ~scratch1_.bit());
462 } 527 }
463 528
464 inline Register object() { return object_; } 529 inline Register object() { return object_; }
465 inline Register address() { return address_; } 530 inline Register address() { return address_; }
466 inline Register scratch0() { return scratch0_; } 531 inline Register scratch0() { return scratch0_; }
532 inline Register scratch1() { return scratch1_; }
467 533
468 private: 534 private:
469 Register object_; 535 Register object_;
470 Register address_; 536 Register address_;
471 Register scratch0_; 537 Register scratch0_;
538 Register scratch1_;
472 539
473 Register GetRegThatIsNotOneOf(Register r1, 540 Register GetRegThatIsNotOneOf(Register r1,
474 Register r2, 541 Register r2,
475 Register r3) { 542 Register r3) {
476 for (int i = 0; i < Register::kNumAllocatableRegisters; i++) { 543 for (int i = 0; i < Register::kNumAllocatableRegisters; i++) {
477 Register candidate = Register::FromAllocationIndex(i); 544 Register candidate = Register::FromAllocationIndex(i);
478 if (candidate.is(r1)) continue; 545 if (candidate.is(r1)) continue;
479 if (candidate.is(r2)) continue; 546 if (candidate.is(r2)) continue;
480 if (candidate.is(r3)) continue; 547 if (candidate.is(r3)) continue;
481 return candidate; 548 return candidate;
482 } 549 }
483 UNREACHABLE(); 550 UNREACHABLE();
484 return no_reg; 551 return no_reg;
485 } 552 }
486 friend class RecordWriteStub; 553 friend class RecordWriteStub;
487 }; 554 };
488 555
489 enum OnNoNeedToInformIncrementalMarker { 556 enum OnNoNeedToInformIncrementalMarker {
490 kReturnOnNoNeedToInformIncrementalMarker, 557 kReturnOnNoNeedToInformIncrementalMarker,
491 kUpdateRememberedSetOnNoNeedToInformIncrementalMarker 558 kUpdateRememberedSetOnNoNeedToInformIncrementalMarker
492 }; 559 };
493 560
494 void Generate(MacroAssembler* masm); 561 void Generate(MacroAssembler* masm);
495 void GenerateIncremental(MacroAssembler* masm); 562 void GenerateIncremental(MacroAssembler* masm, Mode mode);
496 void CheckNeedsToInformIncrementalMarker( 563 void CheckNeedsToInformIncrementalMarker(
497 MacroAssembler* masm, 564 MacroAssembler* masm,
498 OnNoNeedToInformIncrementalMarker on_no_need); 565 OnNoNeedToInformIncrementalMarker on_no_need);
499 void InformIncrementalMarker(MacroAssembler* masm); 566 void InformIncrementalMarker(MacroAssembler* masm, Mode mode);
500 567
501 Major MajorKey() { return RecordWrite; } 568 Major MajorKey() { return RecordWrite; }
502 569
503 int MinorKey() { 570 int MinorKey() {
504 return ObjectBits::encode(object_.code()) | 571 return ObjectBits::encode(object_.code()) |
505 ValueBits::encode(value_.code()) | 572 ValueBits::encode(value_.code()) |
506 AddressBits::encode(address_.code()) | 573 AddressBits::encode(address_.code()) |
507 RememberedSetActionBits::encode(remembered_set_action_) | 574 RememberedSetActionBits::encode(remembered_set_action_) |
508 SaveFPRegsModeBits::encode(save_fp_regs_mode_); 575 SaveFPRegsModeBits::encode(save_fp_regs_mode_);
509 } 576 }
(...skipping 249 matching lines...) Expand 10 before | Expand all | Expand 10 after
759 826
760 class LookupModeBits: public BitField<LookupMode, 0, 1> {}; 827 class LookupModeBits: public BitField<LookupMode, 0, 1> {};
761 828
762 LookupMode mode_; 829 LookupMode mode_;
763 }; 830 };
764 831
765 832
766 } } // namespace v8::internal 833 } } // namespace v8::internal
767 834
768 #endif // V8_ARM_CODE_STUBS_ARM_H_ 835 #endif // V8_ARM_CODE_STUBS_ARM_H_
OLDNEW
« no previous file with comments | « src/arm/assembler-arm.h ('k') | src/arm/code-stubs-arm.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698