Commit 56bf2a11 authored by Zhao Jiazhong's avatar Zhao Jiazhong Committed by Commit Bot

[mips][interpreter] Make IterationBody StackChecks implicit within JumpLoop

Port a447a44f
https://crrev.com/c/2064226

Original Commit Message:

  Since now the IterationBody StackChecks are implicit within JumpLoops,
  we are able to eagerly deopt in them. If we do that, whenever we advance
  to the next bytecode we don't have to advance to the next literal
  bytecode, but instead "advance" in the sense of doing the JumpLoop.

  Adding tests that test this advancing for wide and extra wide JumpLoops.

  Also, marking JumpLoop as needing source positions since now it has
  the ability of causing an interrupt.

Change-Id: Ia435888fbaca8596839aa15dafb8b4e7239981fd
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2119783Reviewed-by: 's avatarSantiago Aboy Solanes <solanes@chromium.org>
Commit-Queue: Zhao Jiazhong <zhaojiazhong-hf@loongson.cn>
Cr-Commit-Position: refs/heads/master@{#66944}
parent 219b0edb
...@@ -911,16 +911,25 @@ static void MaybeOptimizeCode(MacroAssembler* masm, Register feedback_vector, ...@@ -911,16 +911,25 @@ static void MaybeOptimizeCode(MacroAssembler* masm, Register feedback_vector,
// Advance the current bytecode offset. This simulates what all bytecode // Advance the current bytecode offset. This simulates what all bytecode
// handlers do upon completion of the underlying operation. Will bail out to a // handlers do upon completion of the underlying operation. Will bail out to a
// label if the bytecode (without prefix) is a return bytecode. // label if the bytecode (without prefix) is a return bytecode. Will not advance
// the bytecode offset if the current bytecode is a JumpLoop, instead just
// re-executing the JumpLoop to jump to the correct bytecode.
static void AdvanceBytecodeOffsetOrReturn(MacroAssembler* masm, static void AdvanceBytecodeOffsetOrReturn(MacroAssembler* masm,
Register bytecode_array, Register bytecode_array,
Register bytecode_offset, Register bytecode_offset,
Register bytecode, Register scratch1, Register bytecode, Register scratch1,
Register scratch2, Label* if_return) { Register scratch2, Register scratch3,
Label* if_return) {
Register bytecode_size_table = scratch1; Register bytecode_size_table = scratch1;
DCHECK(!AreAliased(bytecode_array, bytecode_offset, bytecode_size_table,
bytecode));
// The bytecode offset value will be increased by one in wide and extra wide
// cases. In the case of having a wide or extra wide JumpLoop bytecode, we
// will restore the original bytecode. In order to simplify the code, we have
// a backup of it.
Register original_bytecode_offset = scratch3;
DCHECK(!AreAliased(bytecode_array, bytecode_offset, bytecode,
bytecode_size_table, original_bytecode_offset));
__ Move(original_bytecode_offset, bytecode_offset);
__ li(bytecode_size_table, ExternalReference::bytecode_size_table_address()); __ li(bytecode_size_table, ExternalReference::bytecode_size_table_address());
// Check if the bytecode is a Wide or ExtraWide prefix bytecode. // Check if the bytecode is a Wide or ExtraWide prefix bytecode.
...@@ -959,10 +968,23 @@ static void AdvanceBytecodeOffsetOrReturn(MacroAssembler* masm, ...@@ -959,10 +968,23 @@ static void AdvanceBytecodeOffsetOrReturn(MacroAssembler* masm,
RETURN_BYTECODE_LIST(JUMP_IF_EQUAL) RETURN_BYTECODE_LIST(JUMP_IF_EQUAL)
#undef JUMP_IF_EQUAL #undef JUMP_IF_EQUAL
// If this is a JumpLoop, re-execute it to perform the jump to the beginning
// of the loop.
Label end, not_jump_loop;
__ Branch(&not_jump_loop, ne, bytecode,
Operand(static_cast<int>(interpreter::Bytecode::kJumpLoop)));
// We need to restore the original bytecode_offset since we might have
// increased it to skip the wide / extra-wide prefix bytecode.
__ Move(bytecode_offset, original_bytecode_offset);
__ jmp(&end);
__ bind(&not_jump_loop);
// Otherwise, load the size of the current bytecode and advance the offset. // Otherwise, load the size of the current bytecode and advance the offset.
__ Lsa(scratch2, bytecode_size_table, bytecode, 2); __ Lsa(scratch2, bytecode_size_table, bytecode, 2);
__ lw(scratch2, MemOperand(scratch2)); __ lw(scratch2, MemOperand(scratch2));
__ Addu(bytecode_offset, bytecode_offset, scratch2); __ Addu(bytecode_offset, bytecode_offset, scratch2);
__ bind(&end);
} }
// Generate code for entering a JS function with the interpreter. // Generate code for entering a JS function with the interpreter.
...@@ -1134,7 +1156,7 @@ void Builtins::Generate_InterpreterEntryTrampoline(MacroAssembler* masm) { ...@@ -1134,7 +1156,7 @@ void Builtins::Generate_InterpreterEntryTrampoline(MacroAssembler* masm) {
__ lbu(a1, MemOperand(a1)); __ lbu(a1, MemOperand(a1));
AdvanceBytecodeOffsetOrReturn(masm, kInterpreterBytecodeArrayRegister, AdvanceBytecodeOffsetOrReturn(masm, kInterpreterBytecodeArrayRegister,
kInterpreterBytecodeOffsetRegister, a1, a2, a3, kInterpreterBytecodeOffsetRegister, a1, a2, a3,
&do_return); t0, &do_return);
__ jmp(&do_dispatch); __ jmp(&do_dispatch);
__ bind(&do_return); __ bind(&do_return);
...@@ -1412,7 +1434,7 @@ void Builtins::Generate_InterpreterEnterBytecodeAdvance(MacroAssembler* masm) { ...@@ -1412,7 +1434,7 @@ void Builtins::Generate_InterpreterEnterBytecodeAdvance(MacroAssembler* masm) {
Label if_return; Label if_return;
AdvanceBytecodeOffsetOrReturn(masm, kInterpreterBytecodeArrayRegister, AdvanceBytecodeOffsetOrReturn(masm, kInterpreterBytecodeArrayRegister,
kInterpreterBytecodeOffsetRegister, a1, a2, a3, kInterpreterBytecodeOffsetRegister, a1, a2, a3,
&if_return); t0, &if_return);
__ bind(&enter_bytecode); __ bind(&enter_bytecode);
// Convert new bytecode offset to a Smi and save in the stackframe. // Convert new bytecode offset to a Smi and save in the stackframe.
......
...@@ -930,15 +930,25 @@ static void MaybeOptimizeCode(MacroAssembler* masm, Register feedback_vector, ...@@ -930,15 +930,25 @@ static void MaybeOptimizeCode(MacroAssembler* masm, Register feedback_vector,
// Advance the current bytecode offset. This simulates what all bytecode // Advance the current bytecode offset. This simulates what all bytecode
// handlers do upon completion of the underlying operation. Will bail out to a // handlers do upon completion of the underlying operation. Will bail out to a
// label if the bytecode (without prefix) is a return bytecode. // label if the bytecode (without prefix) is a return bytecode. Will not advance
// the bytecode offset if the current bytecode is a JumpLoop, instead just
// re-executing the JumpLoop to jump to the correct bytecode.
static void AdvanceBytecodeOffsetOrReturn(MacroAssembler* masm, static void AdvanceBytecodeOffsetOrReturn(MacroAssembler* masm,
Register bytecode_array, Register bytecode_array,
Register bytecode_offset, Register bytecode_offset,
Register bytecode, Register scratch1, Register bytecode, Register scratch1,
Register scratch2, Label* if_return) { Register scratch2, Register scratch3,
Label* if_return) {
Register bytecode_size_table = scratch1; Register bytecode_size_table = scratch1;
DCHECK(!AreAliased(bytecode_array, bytecode_offset, bytecode_size_table,
bytecode)); // The bytecode offset value will be increased by one in wide and extra wide
// cases. In the case of having a wide or extra wide JumpLoop bytecode, we
// will restore the original bytecode. In order to simplify the code, we have
// a backup of it.
Register original_bytecode_offset = scratch3;
DCHECK(!AreAliased(bytecode_array, bytecode_offset, bytecode,
bytecode_size_table, original_bytecode_offset));
__ Move(original_bytecode_offset, bytecode_offset);
__ li(bytecode_size_table, ExternalReference::bytecode_size_table_address()); __ li(bytecode_size_table, ExternalReference::bytecode_size_table_address());
// Check if the bytecode is a Wide or ExtraWide prefix bytecode. // Check if the bytecode is a Wide or ExtraWide prefix bytecode.
...@@ -977,10 +987,23 @@ static void AdvanceBytecodeOffsetOrReturn(MacroAssembler* masm, ...@@ -977,10 +987,23 @@ static void AdvanceBytecodeOffsetOrReturn(MacroAssembler* masm,
RETURN_BYTECODE_LIST(JUMP_IF_EQUAL) RETURN_BYTECODE_LIST(JUMP_IF_EQUAL)
#undef JUMP_IF_EQUAL #undef JUMP_IF_EQUAL
// If this is a JumpLoop, re-execute it to perform the jump to the beginning
// of the loop.
Label end, not_jump_loop;
__ Branch(&not_jump_loop, ne, bytecode,
Operand(static_cast<int>(interpreter::Bytecode::kJumpLoop)));
// We need to restore the original bytecode_offset since we might have
// increased it to skip the wide / extra-wide prefix bytecode.
__ Move(bytecode_offset, original_bytecode_offset);
__ jmp(&end);
__ bind(&not_jump_loop);
// Otherwise, load the size of the current bytecode and advance the offset. // Otherwise, load the size of the current bytecode and advance the offset.
__ Dlsa(scratch2, bytecode_size_table, bytecode, 2); __ Dlsa(scratch2, bytecode_size_table, bytecode, 2);
__ Lw(scratch2, MemOperand(scratch2)); __ Lw(scratch2, MemOperand(scratch2));
__ Daddu(bytecode_offset, bytecode_offset, scratch2); __ Daddu(bytecode_offset, bytecode_offset, scratch2);
__ bind(&end);
} }
// Generate code for entering a JS function with the interpreter. // Generate code for entering a JS function with the interpreter.
...@@ -1153,7 +1176,7 @@ void Builtins::Generate_InterpreterEntryTrampoline(MacroAssembler* masm) { ...@@ -1153,7 +1176,7 @@ void Builtins::Generate_InterpreterEntryTrampoline(MacroAssembler* masm) {
__ Lbu(a1, MemOperand(a1)); __ Lbu(a1, MemOperand(a1));
AdvanceBytecodeOffsetOrReturn(masm, kInterpreterBytecodeArrayRegister, AdvanceBytecodeOffsetOrReturn(masm, kInterpreterBytecodeArrayRegister,
kInterpreterBytecodeOffsetRegister, a1, a2, a3, kInterpreterBytecodeOffsetRegister, a1, a2, a3,
&do_return); a4, &do_return);
__ jmp(&do_dispatch); __ jmp(&do_dispatch);
__ bind(&do_return); __ bind(&do_return);
...@@ -1430,7 +1453,7 @@ void Builtins::Generate_InterpreterEnterBytecodeAdvance(MacroAssembler* masm) { ...@@ -1430,7 +1453,7 @@ void Builtins::Generate_InterpreterEnterBytecodeAdvance(MacroAssembler* masm) {
Label if_return; Label if_return;
AdvanceBytecodeOffsetOrReturn(masm, kInterpreterBytecodeArrayRegister, AdvanceBytecodeOffsetOrReturn(masm, kInterpreterBytecodeArrayRegister,
kInterpreterBytecodeOffsetRegister, a1, a2, a3, kInterpreterBytecodeOffsetRegister, a1, a2, a3,
&if_return); a4, &if_return);
__ bind(&enter_bytecode); __ bind(&enter_bytecode);
// Convert new bytecode offset to a Smi and save in the stackframe. // Convert new bytecode offset to a Smi and save in the stackframe.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment