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

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

Issue 7015043: Fix the GC branch so it compiles and runs on 64 bit. (Closed) Base URL: http://v8.googlecode.com/svn/branches/experimental/gc/
Patch Set: '' Created 9 years, 7 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/x64/assembler-x64-inl.h ('k') | src/x64/code-stubs-x64.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 425 matching lines...) Expand 10 before | Expand all | Expand 10 after
436 const char* GetName() { return "NumberToStringStub"; } 436 const char* GetName() { return "NumberToStringStub"; }
437 437
438 #ifdef DEBUG 438 #ifdef DEBUG
439 void Print() { 439 void Print() {
440 PrintF("NumberToStringStub\n"); 440 PrintF("NumberToStringStub\n");
441 } 441 }
442 #endif 442 #endif
443 }; 443 };
444 444
445 445
446 class RecordWriteStub: public CodeStub {
447 public:
448 RecordWriteStub(Register object,
449 Register value,
450 Register address,
451 EmitRememberedSet emit_remembered_set,
452 SaveFPRegsMode fp_mode)
453 : object_(object),
454 value_(value),
455 address_(address),
456 emit_remembered_set_(emit_remembered_set),
457 save_fp_regs_mode_(fp_mode),
458 regs_(object, // An input reg.
459 address, // An input reg.
460 value) { // One scratch reg.
461 }
462
463 static const byte kTwoByteNopInstruction = 0x3c; // Cmpb al, #imm8.
464 static const byte kSkipNonIncrementalPartInstruction = 0xeb; // Jmp #imm8.
465
466 static byte GetInstruction(bool enable) {
467 // Can't use ternary operator here, because gcc makes an undefined
468 // reference to a static const int.
469 if (enable) {
470 return kSkipNonIncrementalPartInstruction;
471 } else {
472 return kTwoByteNopInstruction;
473 }
474 }
475
476 static void Patch(Code* stub, bool enable) {
477 ASSERT(*stub->instruction_start() == GetInstruction(!enable));
478 *stub->instruction_start() = GetInstruction(enable);
479 }
480
481 private:
482 // This is a helper class for freeing up 3 scratch registers, where the third
483 // is always rcx (needed for shift operations). The input is two registers
484 // that must be preserved and one scratch register provided by the caller.
485 class RegisterAllocation {
486 public:
487 RegisterAllocation(Register object,
488 Register address,
489 Register scratch0)
490 : object_orig_(object),
491 address_orig_(address),
492 scratch0_orig_(scratch0),
493 object_(object),
494 address_(address),
495 scratch0_(scratch0) {
496 ASSERT(!Aliasing(scratch0, object, address, no_reg));
497 scratch1_ = GetRegThatIsNotRcxOr(object_, address_, scratch0_);
498 if (scratch0.is(rcx)) {
499 scratch0_ = GetRegThatIsNotRcxOr(object_, address_, scratch1_);
500 }
501 if (object.is(rcx)) {
502 object_ = GetRegThatIsNotRcxOr(address_, scratch0_, scratch1_);
503 }
504 if (address.is(rcx)) {
505 address_ = GetRegThatIsNotRcxOr(object_, scratch0_, scratch1_);
506 }
507 ASSERT(!Aliasing(scratch0_, object_, address_, rcx));
508 }
509
510 void Save(MacroAssembler* masm) {
511 ASSERT(!address_orig_.is(object_));
512 ASSERT(object_.is(object_orig_) || address_.is(address_orig_));
513 ASSERT(!Aliasing(object_, address_, scratch1_, scratch0_));
514 ASSERT(!Aliasing(object_orig_, address_, scratch1_, scratch0_));
515 ASSERT(!Aliasing(object_, address_orig_, scratch1_, scratch0_));
516 // We don't have to save scratch0_orig_ because it was given to us as
517 // a scratch register. But if we had to switch to a different reg then
518 // we should save the new scratch0_.
519 if (!scratch0_.is(scratch0_orig_)) masm->push(scratch0_);
520 if (!rcx.is(scratch0_orig_) &&
521 !rcx.is(object_orig_) &&
522 !rcx.is(address_orig_)) {
523 masm->push(rcx);
524 }
525 masm->push(scratch1_);
526 if (!address_.is(address_orig_)) {
527 masm->push(address_);
528 masm->movq(address_, address_orig_);
529 }
530 if (!object_.is(object_orig_)) {
531 masm->push(object_);
532 masm->movq(object_, object_orig_);
533 }
534 }
535
536 void Restore(MacroAssembler* masm) {
537 // These will have been preserved the entire time, so we just need to move
538 // them back. Only in one case is the orig_ reg different from the plain
539 // one, since only one of them can alias with rcx.
540 if (!object_.is(object_orig_)) {
541 masm->movq(object_orig_, object_);
542 masm->pop(object_);
543 }
544 if (!address_.is(address_orig_)) {
545 masm->movq(address_orig_, address_);
546 masm->pop(address_);
547 }
548 masm->pop(scratch1_);
549 if (!rcx.is(scratch0_orig_) &&
550 !rcx.is(object_orig_) &&
551 !rcx.is(address_orig_)) {
552 masm->pop(rcx);
553 }
554 if (!scratch0_.is(scratch0_orig_)) masm->pop(scratch0_);
555 }
556
557 // If we have to call into C then we need to save and restore all caller-
558 // saved registers that were not already preserved.
559
560 // The three scratch registers (incl. rcx)
561 // will be restored by other means so we don't bother pushing them here.
562 void SaveCallerSaveRegisters(MacroAssembler* masm, SaveFPRegsMode mode) {
563 masm->int3(); // TODO(gc): Save the caller save registers.
564 if (mode == kSaveFPRegs) {
565 CpuFeatures::Scope scope(SSE2);
566 masm->subq(rsp,
567 Immediate(kDoubleSize * (XMMRegister::kNumRegisters - 1)));
568 // Save all XMM registers except XMM0.
569 for (int i = XMMRegister::kNumRegisters - 1; i > 0; i--) {
570 XMMRegister reg = XMMRegister::from_code(i);
571 masm->movsd(Operand(rsp, (i - 1) * kDoubleSize), reg);
572 }
573 }
574 }
575
576 inline void RestoreCallerSaveRegisters(MacroAssembler*masm,
577 SaveFPRegsMode mode) {
578 if (mode == kSaveFPRegs) {
579 CpuFeatures::Scope scope(SSE2);
580 // Restore all XMM registers except XMM0.
581 for (int i = XMMRegister::kNumRegisters - 1; i > 0; i--) {
582 XMMRegister reg = XMMRegister::from_code(i);
583 masm->movsd(reg, Operand(rsp, (i - 1) * kDoubleSize));
584 }
585 masm->addq(rsp,
586 Immediate(kDoubleSize * (XMMRegister::kNumRegisters - 1)));
587 }
588 masm->int3(); // TODO(gc): Restore the caller save registers.
589 }
590
591 inline Register object() { return object_; }
592 inline Register address() { return address_; }
593 inline Register scratch0() { return scratch0_; }
594 inline Register scratch1() { return scratch1_; }
595
596 private:
597 Register object_orig_;
598 Register address_orig_;
599 Register scratch0_orig_;
600 Register object_;
601 Register address_;
602 Register scratch0_;
603 Register scratch1_;
604 // Third scratch register is always rcx.
605
606 Register GetRegThatIsNotRcxOr(Register r1,
607 Register r2,
608 Register r3) {
609 for (int i = 0; i < Register::kNumAllocatableRegisters; i++) {
610 Register candidate = Register::FromAllocationIndex(i);
611 if (candidate.is(rcx)) continue;
612 if (candidate.is(r1)) continue;
613 if (candidate.is(r2)) continue;
614 if (candidate.is(r3)) continue;
615 return candidate;
616 }
617 UNREACHABLE();
618 return no_reg;
619 }
620 friend class RecordWriteStub;
621 };
622
623 void Generate(MacroAssembler* masm);
624 void GenerateIncremental(MacroAssembler* masm);
625
626 Major MajorKey() { return RecordWrite; }
627
628 int MinorKey() {
629 return ObjectBits::encode(object_.code()) |
630 ValueBits::encode(value_.code()) |
631 AddressBits::encode(address_.code()) |
632 EmitRememberedSetBits::encode(emit_remembered_set_) |
633 SaveFPRegsModeBits::encode(save_fp_regs_mode_);
634 }
635
636 class ObjectBits: public BitField<int, 0, 4> {};
637 class ValueBits: public BitField<int, 4, 4> {};
638 class AddressBits: public BitField<int, 8, 4> {};
639 class EmitRememberedSetBits: public BitField<EmitRememberedSet, 12, 1> {};
640 class SaveFPRegsModeBits: public BitField<SaveFPRegsMode, 13, 1> {};
641
642 Register object_;
643 Register value_;
644 Register address_;
645 EmitRememberedSet emit_remembered_set_;
646 SaveFPRegsMode save_fp_regs_mode_;
647 Label slow_;
648 RegisterAllocation regs_;
649 };
650
651
446 } } // namespace v8::internal 652 } } // namespace v8::internal
447 653
448 #endif // V8_X64_CODE_STUBS_X64_H_ 654 #endif // V8_X64_CODE_STUBS_X64_H_
OLDNEW
« no previous file with comments | « src/x64/assembler-x64-inl.h ('k') | src/x64/code-stubs-x64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698