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

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 un-nop-ish nop instruction. 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) | (B24 | B20));
414 ASSERT(Assembler::IsTstImmediate(masm->instr_at(pos)));
415 }
416
417 static void PatchNopIntoBranch(MacroAssembler* masm, int pos) {
418 masm->instr_at_put(pos, (masm->instr_at(pos) & ~(B24 | B20)) | B27);
419 ASSERT(Assembler::IsBranch(masm->instr_at(pos)));
420 }
421
412 static Mode GetMode(Code* stub) { 422 static Mode GetMode(Code* stub) {
423 Instr first_instruction = Assembler::instr_at(stub->instruction_start());
424 Instr second_instruction = Assembler::instr_at(stub->instruction_start() +
425 Assembler::kInstrSize);
426
427 if (Assembler::IsBranch(first_instruction)) {
428 return INCREMENTAL;
429 }
430
431 ASSERT(Assembler::IsTstImmediate(first_instruction));
432
433 if (Assembler::IsBranch(second_instruction)) {
434 return INCREMENTAL_COMPACTION;
435 }
436
437 ASSERT(Assembler::IsTstImmediate(second_instruction));
438
413 return STORE_BUFFER_ONLY; 439 return STORE_BUFFER_ONLY;
414 } 440 }
415 441
416 static void Patch(Code* stub, Mode mode) { 442 static void Patch(Code* stub, Mode mode) {
417 ASSERT(mode == STORE_BUFFER_ONLY); 443 MacroAssembler masm(NULL,
444 stub->instruction_start(),
445 stub->instruction_size());
446 switch (mode) {
447 case STORE_BUFFER_ONLY:
448 ASSERT(GetMode(stub) == INCREMENTAL ||
449 GetMode(stub) == INCREMENTAL_COMPACTION);
450 PatchBranchIntoNop(&masm, 0);
451 PatchBranchIntoNop(&masm, Assembler::kInstrSize);
452 break;
453 case INCREMENTAL:
454 ASSERT(GetMode(stub) == STORE_BUFFER_ONLY);
455 PatchNopIntoBranch(&masm, 0);
456 break;
457 case INCREMENTAL_COMPACTION:
458 ASSERT(GetMode(stub) == STORE_BUFFER_ONLY);
459 PatchNopIntoBranch(&masm, Assembler::kInstrSize);
460 break;
461 }
462 ASSERT(GetMode(stub) == mode);
463 CPU::FlushICache(stub->instruction_start(), 2 * Assembler::kInstrSize);
418 } 464 }
419 465
420 private: 466 private:
421 // This is a helper class for freeing up 3 scratch registers. The input is 467 // 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 468 // two registers that must be preserved and one scratch register provided by
423 // the caller. 469 // the caller.
424 class RegisterAllocation { 470 class RegisterAllocation {
425 public: 471 public:
426 RegisterAllocation(Register object, 472 RegisterAllocation(Register object,
427 Register address, 473 Register address,
428 Register scratch0) 474 Register scratch0)
429 : object_(object), 475 : object_(object),
430 address_(address), 476 address_(address),
431 scratch0_(scratch0) { 477 scratch0_(scratch0) {
478 ASSERT(!AreAliased(scratch0, object, address, no_reg));
479 scratch1_ = GetRegThatIsNotOneOf(object_, address_, scratch0_);
432 } 480 }
481
482 void Save(MacroAssembler* masm) {
483 ASSERT(!AreAliased(object_, address_, scratch1_, scratch0_));
484 // We don't have to save scratch0_ because it was given to us as
485 // a scratch register.
486 masm->push(scratch1_);
487 }
488
489 void Restore(MacroAssembler* masm) {
490 masm->pop(scratch1_);
491 }
492
493 // If we have to call into C then we need to save and restore all caller-
494 // saved registers that were not already preserved. The scratch registers
495 // will be restored by other means so we don't bother pushing them here.
433 void SaveCallerSaveRegisters(MacroAssembler* masm, SaveFPRegsMode mode) { 496 void SaveCallerSaveRegisters(MacroAssembler* masm, SaveFPRegsMode mode) {
434 UNREACHABLE(); // TODO(gc): Save the caller save registers. 497 masm->stm(db_w, sp, (kCallerSaved | lr.bit()) & ~scratch1_.bit());
435 if (mode == kSaveFPRegs) { 498 if (mode == kSaveFPRegs) {
436 CpuFeatures::Scope scope(SSE2); 499 CpuFeatures::Scope scope(VFP3);
437 masm->sub(sp, 500 masm->sub(sp,
438 sp, 501 sp,
439 Operand(kDoubleSize * (DwVfpRegister::kNumRegisters - 1))); 502 Operand(kDoubleSize * (DwVfpRegister::kNumRegisters - 1)));
440 // Save all VFP registers except d0. 503 // Save all VFP registers except d0.
441 for (int i = DwVfpRegister::kNumRegisters - 1; i > 0; i--) { 504 for (int i = DwVfpRegister::kNumRegisters - 1; i > 0; i--) {
442 DwVfpRegister reg = DwVfpRegister::from_code(i); 505 DwVfpRegister reg = DwVfpRegister::from_code(i);
443 masm->vstr(reg, MemOperand(sp, (i - 1) * kDoubleSize)); 506 masm->vstr(reg, MemOperand(sp, (i - 1) * kDoubleSize));
444 } 507 }
445 } 508 }
446 } 509 }
447 510
448 inline void RestoreCallerSaveRegisters(MacroAssembler*masm, 511 inline void RestoreCallerSaveRegisters(MacroAssembler*masm,
449 SaveFPRegsMode mode) { 512 SaveFPRegsMode mode) {
450 if (mode == kSaveFPRegs) { 513 if (mode == kSaveFPRegs) {
451 CpuFeatures::Scope scope(SSE2); 514 CpuFeatures::Scope scope(VFP3);
452 // Restore all VFP registers except d0. 515 // Restore all VFP registers except d0.
453 for (int i = DwVfpRegister::kNumRegisters - 1; i > 0; i--) { 516 for (int i = DwVfpRegister::kNumRegisters - 1; i > 0; i--) {
454 DwVfpRegister reg = DwVfpRegister::from_code(i); 517 DwVfpRegister reg = DwVfpRegister::from_code(i);
455 masm->vldr(reg, MemOperand(sp, (i - 1) * kDoubleSize)); 518 masm->vldr(reg, MemOperand(sp, (i - 1) * kDoubleSize));
456 } 519 }
457 masm->add(sp, 520 masm->add(sp,
458 sp, 521 sp,
459 Operand(kDoubleSize * (DwVfpRegister::kNumRegisters - 1))); 522 Operand(kDoubleSize * (DwVfpRegister::kNumRegisters - 1)));
460 } 523 }
461 UNREACHABLE(); // TODO(gc): Restore the caller save registers. 524 masm->ldm(ia_w, sp, (kCallerSaved | lr.bit()) & ~scratch1_.bit());
462 } 525 }
463 526
464 inline Register object() { return object_; } 527 inline Register object() { return object_; }
465 inline Register address() { return address_; } 528 inline Register address() { return address_; }
466 inline Register scratch0() { return scratch0_; } 529 inline Register scratch0() { return scratch0_; }
530 inline Register scratch1() { return scratch1_; }
467 531
468 private: 532 private:
469 Register object_; 533 Register object_;
470 Register address_; 534 Register address_;
471 Register scratch0_; 535 Register scratch0_;
536 Register scratch1_;
472 537
473 Register GetRegThatIsNotOneOf(Register r1, 538 Register GetRegThatIsNotOneOf(Register r1,
474 Register r2, 539 Register r2,
475 Register r3) { 540 Register r3) {
476 for (int i = 0; i < Register::kNumAllocatableRegisters; i++) { 541 for (int i = 0; i < Register::kNumAllocatableRegisters; i++) {
477 Register candidate = Register::FromAllocationIndex(i); 542 Register candidate = Register::FromAllocationIndex(i);
478 if (candidate.is(r1)) continue; 543 if (candidate.is(r1)) continue;
479 if (candidate.is(r2)) continue; 544 if (candidate.is(r2)) continue;
480 if (candidate.is(r3)) continue; 545 if (candidate.is(r3)) continue;
481 return candidate; 546 return candidate;
482 } 547 }
483 UNREACHABLE(); 548 UNREACHABLE();
484 return no_reg; 549 return no_reg;
485 } 550 }
486 friend class RecordWriteStub; 551 friend class RecordWriteStub;
487 }; 552 };
488 553
489 enum OnNoNeedToInformIncrementalMarker { 554 enum OnNoNeedToInformIncrementalMarker {
490 kReturnOnNoNeedToInformIncrementalMarker, 555 kReturnOnNoNeedToInformIncrementalMarker,
491 kUpdateRememberedSetOnNoNeedToInformIncrementalMarker 556 kUpdateRememberedSetOnNoNeedToInformIncrementalMarker
492 }; 557 };
493 558
494 void Generate(MacroAssembler* masm); 559 void Generate(MacroAssembler* masm);
495 void GenerateIncremental(MacroAssembler* masm); 560 void GenerateIncremental(MacroAssembler* masm, Mode mode);
496 void CheckNeedsToInformIncrementalMarker( 561 void CheckNeedsToInformIncrementalMarker(
497 MacroAssembler* masm, 562 MacroAssembler* masm,
498 OnNoNeedToInformIncrementalMarker on_no_need); 563 OnNoNeedToInformIncrementalMarker on_no_need);
499 void InformIncrementalMarker(MacroAssembler* masm); 564 void InformIncrementalMarker(MacroAssembler* masm, Mode mode);
500 565
501 Major MajorKey() { return RecordWrite; } 566 Major MajorKey() { return RecordWrite; }
502 567
503 int MinorKey() { 568 int MinorKey() {
504 return ObjectBits::encode(object_.code()) | 569 return ObjectBits::encode(object_.code()) |
505 ValueBits::encode(value_.code()) | 570 ValueBits::encode(value_.code()) |
506 AddressBits::encode(address_.code()) | 571 AddressBits::encode(address_.code()) |
507 RememberedSetActionBits::encode(remembered_set_action_) | 572 RememberedSetActionBits::encode(remembered_set_action_) |
508 SaveFPRegsModeBits::encode(save_fp_regs_mode_); 573 SaveFPRegsModeBits::encode(save_fp_regs_mode_);
509 } 574 }
(...skipping 249 matching lines...) Expand 10 before | Expand all | Expand 10 after
759 824
760 class LookupModeBits: public BitField<LookupMode, 0, 1> {}; 825 class LookupModeBits: public BitField<LookupMode, 0, 1> {};
761 826
762 LookupMode mode_; 827 LookupMode mode_;
763 }; 828 };
764 829
765 830
766 } } // namespace v8::internal 831 } } // namespace v8::internal
767 832
768 #endif // V8_ARM_CODE_STUBS_ARM_H_ 833 #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