Reviewers: Paul Lind, kisg, kilvadyb, dusmil, danno,

Message:
PTAL.

Description:
MIPS: Fix and simplify code aging.

This commit fixes a lot of test failures that we saw earlier in the buildbots
(http://build.chromium.org/p/client.v8/builders/V8%20Linux%20-%20mips%20-%20sim/builds/3034/steps/Check/logs/stdio).

In some very rare cases the code age stub address can be 0xXXXX0000 and in this case the li maco instruction emits only 1 instruction (instead of the expected 2). Thus the code age sequence will be 6 instructions long instead of 7, which
breaks the code aging feature. This change makes sure that li always emits 2
instructions and it also simplifies the code aging sequence.

Also fixes a small mistake in the simulator at the jalr instruction.

BUG=

Please review this at https://codereview.chromium.org/83583003/

SVN Base: https://v8.googlecode.com/svn/branches/bleeding_edge

Affected files (+33, -34 lines):
  M src/mips/assembler-mips-inl.h
  M src/mips/builtins-mips.cc
  M src/mips/codegen-mips.cc
  M src/mips/macro-assembler-mips.cc
  M src/mips/simulator-mips.h
  M src/mips/simulator-mips.cc


Index: src/mips/assembler-mips-inl.h
diff --git a/src/mips/assembler-mips-inl.h b/src/mips/assembler-mips-inl.h
index d5af5b2ec6d2521ea85a3a7129ad4a108874e68f..514b3aaa4f00247abdf680935b18edaedcbe3efc 100644
--- a/src/mips/assembler-mips-inl.h
+++ b/src/mips/assembler-mips-inl.h
@@ -260,16 +260,14 @@ Handle<Object> RelocInfo::code_age_stub_handle(Assembler* origin) {
 Code* RelocInfo::code_age_stub() {
   ASSERT(rmode_ == RelocInfo::CODE_AGE_SEQUENCE);
   return Code::GetCodeFromTargetAddress(
-      Memory::Address_at(pc_ + Assembler::kInstrSize *
-                         (kNoCodeAgeSequenceLength - 1)));
+      Assembler::target_address_at(pc_ + Assembler::kInstrSize));
 }


 void RelocInfo::set_code_age_stub(Code* stub) {
   ASSERT(rmode_ == RelocInfo::CODE_AGE_SEQUENCE);
-  Memory::Address_at(pc_ + Assembler::kInstrSize *
-                     (kNoCodeAgeSequenceLength - 1)) =
-      stub->instruction_start();
+  Assembler::set_target_address_at(pc_ + Assembler::kInstrSize,
+                                   stub->instruction_start());
 }


Index: src/mips/builtins-mips.cc
diff --git a/src/mips/builtins-mips.cc b/src/mips/builtins-mips.cc
index d2641df6e675dcc5f08d4812874e723a493bc80a..19f3cdf4ff81bc837b7ba0958f2da6a63118ee90 100644
--- a/src/mips/builtins-mips.cc
+++ b/src/mips/builtins-mips.cc
@@ -813,12 +813,9 @@ static void GenerateMakeCodeYoungAgainCommon(MacroAssembler* masm) { // internal frame to make the code faster, since we shouldn't have to do stack
   // crawls in MakeCodeYoung. This seems a bit fragile.

-  __ mov(a0, ra);
-  // Adjust a0 to point to the head of the PlatformCodeAge sequence
+  // Set a0 to point to the head of the PlatformCodeAge sequence.
   __ Subu(a0, a0,
       Operand((kNoCodeAgeSequenceLength - 1) * Assembler::kInstrSize));
-  // Restore the original return address of the function
-  __ mov(ra, at);

// The following registers must be saved and restored when calling through to
   // the runtime:
@@ -855,12 +852,9 @@ void Builtins::Generate_MarkCodeAsExecutedOnce(MacroAssembler* masm) { // save/restore the registers without worrying about which of them contain
   // pointers.

-  __ mov(a0, ra);
-  // Adjust a0 to point to the head of the PlatformCodeAge sequence
+  // Set a0 to point to the head of the PlatformCodeAge sequence.
   __ Subu(a0, a0,
       Operand((kNoCodeAgeSequenceLength - 1) * Assembler::kInstrSize));
-  // Restore the original return address of the function
-  __ mov(ra, at);

// The following registers must be saved and restored when calling through to
   // the runtime:
Index: src/mips/codegen-mips.cc
diff --git a/src/mips/codegen-mips.cc b/src/mips/codegen-mips.cc
index 221a0e1b4e2a81e01bc6cf5a93fdd0007d2b8469..3a87c5af88658b9c848e8c56aeafe7e46a87c76f 100644
--- a/src/mips/codegen-mips.cc
+++ b/src/mips/codegen-mips.cc
@@ -642,8 +642,8 @@ void Code::GetCodeAgeAndParity(byte* sequence, Age* age,
     *age = kNoAgeCodeAge;
     *parity = NO_MARKING_PARITY;
   } else {
-    Address target_address = Memory::Address_at(
-        sequence + Assembler::kInstrSize * (kNoCodeAgeSequenceLength - 1));
+    Address target_address = Assembler::target_address_at(
+        sequence + Assembler::kInstrSize);
     Code* stub = GetCodeFromTargetAddress(target_address);
     GetCodeAgeAndParity(stub, age, parity);
   }
@@ -662,17 +662,18 @@ void Code::PatchPlatformCodeAge(Isolate* isolate,
   } else {
     Code* stub = GetCodeAgeStub(isolate, age, parity);
     CodePatcher patcher(sequence, young_length / Assembler::kInstrSize);
-    // Mark this code sequence for FindPlatformCodeAgeSequence()
+    // Mark this code sequence for FindPlatformCodeAgeSequence().
     patcher.masm()->nop(Assembler::CODE_AGE_MARKER_NOP);
-    // Save the function's original return address
-    // (it will be clobbered by Call(t9))
-    patcher.masm()->mov(at, ra);
-    // Load the stub address to t9 and call it
-    patcher.masm()->li(t9,
-        Operand(reinterpret_cast<uint32_t>(stub->instruction_start())));
-    patcher.masm()->Call(t9);
-    // Record the stub address in the empty space for GetCodeAgeAndParity()
-    patcher.masm()->emit_code_stub_address(stub);
+    // Load the stub address to t9 and call it,
+ // GetCodeAgeAndParity() extracts the stub address from this instruction.
+    patcher.masm()->li(
+        t9,
+        Operand(reinterpret_cast<uint32_t>(stub->instruction_start())),
+        CONSTANT_SIZE);
+    patcher.masm()->nop();  // Prevent jalr to jal optimization.
+    patcher.masm()->jalr(t9, a0);
+    patcher.masm()->nop();  // Branch delay slot nop.
+    patcher.masm()->nop();  // Pad the empty space.
   }
 }

Index: src/mips/macro-assembler-mips.cc
diff --git a/src/mips/macro-assembler-mips.cc b/src/mips/macro-assembler-mips.cc index cb336f3b0b9262b3c2d12628bec9ec9679a43799..cdfbae39c2a27242f7745cc9cd5d039d11060428 100644
--- a/src/mips/macro-assembler-mips.cc
+++ b/src/mips/macro-assembler-mips.cc
@@ -4526,15 +4526,15 @@ void MacroAssembler::Prologue(PrologueFrameMode frame_mode) {
       // Pre-age the code.
       Code* stub = Code::GetPreAgedCodeAgeStub(isolate());
       nop(Assembler::CODE_AGE_MARKER_NOP);
-      // Save the function's original return address
-      // (it will be clobbered by Call(t9)).
-      mov(at, ra);
-      // Load the stub address to t9 and call it.
+      // Load the stub address to t9 and call it,
+ // GetCodeAgeAndParity() extracts the stub address from this instruction.
       li(t9,
-         Operand(reinterpret_cast<uint32_t>(stub->instruction_start())));
-      Call(t9);
- // Record the stub address in the empty space for GetCodeAgeAndParity().
-      emit_code_stub_address(stub);
+         Operand(reinterpret_cast<uint32_t>(stub->instruction_start())),
+         CONSTANT_SIZE);
+      nop();  // Prevent jalr to jal optimization.
+      jalr(t9, a0);
+      nop();  // Branch delay slot nop.
+      nop();  // Pad the empty space.
     } else {
       Push(ra, fp, cp, a1);
       nop(Assembler::CODE_AGE_SEQUENCE_NOP);
Index: src/mips/simulator-mips.cc
diff --git a/src/mips/simulator-mips.cc b/src/mips/simulator-mips.cc
index 5a96efe9c1d529338f10b6a0e657804d74e59ce8..acc65251e23f97973d991c65f4078385cec56c14 100644
--- a/src/mips/simulator-mips.cc
+++ b/src/mips/simulator-mips.cc
@@ -1722,6 +1722,7 @@ void Simulator::ConfigureTypeRegister(Instruction* instr,
                                       int64_t& i64hilo,
                                       uint64_t& u64hilo,
                                       int32_t& next_pc,
+                                      int32_t& return_addr_reg,
                                       bool& do_interrupt) {
   // Every local variable declared here needs to be const.
   // This is to make sure that changed values are sent back to
@@ -1782,6 +1783,7 @@ void Simulator::ConfigureTypeRegister(Instruction* instr,
         case JR:
         case JALR:
           next_pc = get_register(instr->RsValue());
+          return_addr_reg = instr->RdValue();
           break;
         case SLL:
           alu_out = rt << sa;
@@ -1986,6 +1988,7 @@ void Simulator::DecodeTypeRegister(Instruction* instr) {
   int32_t current_pc = get_pc();
   // Next pc
   int32_t next_pc = 0;
+  int32_t return_addr_reg = 31;

   // Set up the variables if needed before executing the instruction.
   ConfigureTypeRegister(instr,
@@ -1993,6 +1996,7 @@ void Simulator::DecodeTypeRegister(Instruction* instr) {
                         i64hilo,
                         u64hilo,
                         next_pc,
+                        return_addr_reg,
                         do_interrupt);

   // ---------- Raise exceptions triggered.
@@ -2258,7 +2262,8 @@ void Simulator::DecodeTypeRegister(Instruction* instr) {
           Instruction* branch_delay_instr = reinterpret_cast<Instruction*>(
               current_pc+Instruction::kInstrSize);
           BranchDelayInstructionDecode(branch_delay_instr);
-          set_register(31, current_pc + 2 * Instruction::kInstrSize);
+          set_register(return_addr_reg,
+                       current_pc + 2 * Instruction::kInstrSize);
           set_pc(next_pc);
           pc_modified_ = true;
           break;
Index: src/mips/simulator-mips.h
diff --git a/src/mips/simulator-mips.h b/src/mips/simulator-mips.h
index 601cd6d99d113c867419fac06ffdcbc3de5f938c..d9fd10f245c3617e332bfdefeb8b9b3b2a099826 100644
--- a/src/mips/simulator-mips.h
+++ b/src/mips/simulator-mips.h
@@ -289,6 +289,7 @@ class Simulator {
                              int64_t& i64hilo,
                              uint64_t& u64hilo,
                              int32_t& next_pc,
+                             int32_t& return_addr_reg,
                              bool& do_interrupt);

   void DecodeTypeImmediate(Instruction* instr);


--
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
--- You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/groups/opt_out.

Reply via email to