Commit abac06aa authored by Junliang Yan's avatar Junliang Yan Committed by Commit Bot

PPC/s390: [Ignition] [TurboFan] Generate speculation poison in code generator.

Port a021b6c4

Original Commit Message:

    Moves generation of speculation poison to be based on the PC target vs the
    actual PC being executed. The speculation poison is generated in the prologue
    of the generated code if CompilationInfo::kGenerateSpeculationPoison is set.
    The result is stored in a known register, which can then be read using the
    SpeculationPoison machine node.

    Currently we need to ensure the SpeculationPoison node is scheduled right after
    the code prologue so that the poison register doesn't get clobbered. This is
    currently not verified, however it's only use is in RawMachineAssembler where
    it is manually scheduled early.

    The Ignition bytecode handlers are updated to use this speculation poison
    rather than one generated by comparing the target bytecode.

R=rmcilroy@chromium.org, joransiu@ca.ibm.com, michael_dawson@ca.ibm.com
BUG=chromium:798964
LOG=N

Change-Id: I4b9a1b0865b6164171cf83f0e45c36c69ac08a18
Reviewed-on: https://chromium-review.googlesource.com/914848Reviewed-by: 's avatarJoran Siu <joransiu@ca.ibm.com>
Commit-Queue: Junliang Yan <jyan@ca.ibm.com>
Cr-Commit-Position: refs/heads/master@{#51273}
parent 8f489e73
...@@ -1034,13 +1034,12 @@ void Builtins::Generate_InterpreterEntryTrampoline(MacroAssembler* masm) { ...@@ -1034,13 +1034,12 @@ void Builtins::Generate_InterpreterEntryTrampoline(MacroAssembler* masm) {
__ mov(kInterpreterDispatchTableRegister, __ mov(kInterpreterDispatchTableRegister,
Operand(ExternalReference::interpreter_dispatch_table_address( Operand(ExternalReference::interpreter_dispatch_table_address(
masm->isolate()))); masm->isolate())));
__ lbzx(kInterpreterTargetBytecodeRegister, __ lbzx(r6, MemOperand(kInterpreterBytecodeArrayRegister,
MemOperand(kInterpreterBytecodeArrayRegister, kInterpreterBytecodeOffsetRegister));
kInterpreterBytecodeOffsetRegister)); __ ShiftLeftImm(r6, r6, Operand(kPointerSizeLog2));
__ ShiftLeftImm(ip, kInterpreterTargetBytecodeRegister, __ LoadPX(kJavaScriptCallCodeStartRegister,
Operand(kPointerSizeLog2)); MemOperand(kInterpreterDispatchTableRegister, r6));
__ LoadPX(ip, MemOperand(kInterpreterDispatchTableRegister, ip)); __ Call(kJavaScriptCallCodeStartRegister);
__ Call(ip);
masm->isolate()->heap()->SetInterpreterEntryReturnPCOffset(masm->pc_offset()); masm->isolate()->heap()->SetInterpreterEntryReturnPCOffset(masm->pc_offset());
...@@ -1263,13 +1262,12 @@ static void Generate_InterpreterEnterBytecode(MacroAssembler* masm) { ...@@ -1263,13 +1262,12 @@ static void Generate_InterpreterEnterBytecode(MacroAssembler* masm) {
__ SmiUntag(kInterpreterBytecodeOffsetRegister); __ SmiUntag(kInterpreterBytecodeOffsetRegister);
// Dispatch to the target bytecode. // Dispatch to the target bytecode.
__ lbzx(kInterpreterTargetBytecodeRegister, __ lbzx(ip, MemOperand(kInterpreterBytecodeArrayRegister,
MemOperand(kInterpreterBytecodeArrayRegister, kInterpreterBytecodeOffsetRegister));
kInterpreterBytecodeOffsetRegister)); __ ShiftLeftImm(ip, ip, Operand(kPointerSizeLog2));
__ ShiftLeftImm(ip, kInterpreterTargetBytecodeRegister, __ LoadPX(kJavaScriptCallCodeStartRegister,
Operand(kPointerSizeLog2)); MemOperand(kInterpreterDispatchTableRegister, ip));
__ LoadPX(ip, MemOperand(kInterpreterDispatchTableRegister, ip)); __ Jump(kJavaScriptCallCodeStartRegister);
__ Jump(ip);
} }
void Builtins::Generate_InterpreterEnterBytecodeAdvance(MacroAssembler* masm) { void Builtins::Generate_InterpreterEnterBytecodeAdvance(MacroAssembler* masm) {
......
...@@ -1033,13 +1033,12 @@ void Builtins::Generate_InterpreterEntryTrampoline(MacroAssembler* masm) { ...@@ -1033,13 +1033,12 @@ void Builtins::Generate_InterpreterEntryTrampoline(MacroAssembler* masm) {
Operand(ExternalReference::interpreter_dispatch_table_address( Operand(ExternalReference::interpreter_dispatch_table_address(
masm->isolate()))); masm->isolate())));
__ LoadlB(kInterpreterTargetBytecodeRegister, __ LoadlB(r5, MemOperand(kInterpreterBytecodeArrayRegister,
MemOperand(kInterpreterBytecodeArrayRegister, kInterpreterBytecodeOffsetRegister));
kInterpreterBytecodeOffsetRegister)); __ ShiftLeftP(r5, r5, Operand(kPointerSizeLog2));
__ ShiftLeftP(ip, kInterpreterTargetBytecodeRegister, __ LoadP(kJavaScriptCallCodeStartRegister,
Operand(kPointerSizeLog2)); MemOperand(kInterpreterDispatchTableRegister, r5));
__ LoadP(ip, MemOperand(kInterpreterDispatchTableRegister, ip)); __ Call(kJavaScriptCallCodeStartRegister);
__ Call(ip);
masm->isolate()->heap()->SetInterpreterEntryReturnPCOffset(masm->pc_offset()); masm->isolate()->heap()->SetInterpreterEntryReturnPCOffset(masm->pc_offset());
...@@ -1260,13 +1259,12 @@ static void Generate_InterpreterEnterBytecode(MacroAssembler* masm) { ...@@ -1260,13 +1259,12 @@ static void Generate_InterpreterEnterBytecode(MacroAssembler* masm) {
__ SmiUntag(kInterpreterBytecodeOffsetRegister); __ SmiUntag(kInterpreterBytecodeOffsetRegister);
// Dispatch to the target bytecode. // Dispatch to the target bytecode.
__ LoadlB(kInterpreterTargetBytecodeRegister, __ LoadlB(ip, MemOperand(kInterpreterBytecodeArrayRegister,
MemOperand(kInterpreterBytecodeArrayRegister, kInterpreterBytecodeOffsetRegister));
kInterpreterBytecodeOffsetRegister)); __ ShiftLeftP(ip, ip, Operand(kPointerSizeLog2));
__ ShiftLeftP(ip, kInterpreterTargetBytecodeRegister, __ LoadP(kJavaScriptCallCodeStartRegister,
Operand(kPointerSizeLog2)); MemOperand(kInterpreterDispatchTableRegister, ip));
__ LoadP(ip, MemOperand(kInterpreterDispatchTableRegister, ip)); __ Jump(kJavaScriptCallCodeStartRegister);
__ Jump(ip);
} }
void Builtins::Generate_InterpreterEnterBytecodeAdvance(MacroAssembler* masm) { void Builtins::Generate_InterpreterEnterBytecodeAdvance(MacroAssembler* masm) {
......
...@@ -807,6 +807,31 @@ void CodeGenerator::BailoutIfDeoptimized() { ...@@ -807,6 +807,31 @@ void CodeGenerator::BailoutIfDeoptimized() {
__ Jump(code, RelocInfo::CODE_TARGET, ne, cr0); __ Jump(code, RelocInfo::CODE_TARGET, ne, cr0);
} }
void CodeGenerator::GenerateSpeculationPoison() {
Register scratch = kScratchReg;
Label current_pc;
__ mov_label_addr(scratch, &current_pc);
__ bind(&current_pc);
__ subi(scratch, scratch, Operand(__ pc_offset()));
// Calculate a mask which has all bits set in the normal case, but has all
// bits cleared if we are speculatively executing the wrong PC.
// difference = (current - expected) | (expected - current)
// poison = ~(difference >> (kBitsPerPointer - 1))
__ mr(kSpeculationPoisonRegister, scratch);
__ sub(kSpeculationPoisonRegister, kSpeculationPoisonRegister,
kJavaScriptCallCodeStartRegister);
__ sub(kJavaScriptCallCodeStartRegister, kJavaScriptCallCodeStartRegister,
scratch);
__ orx(kSpeculationPoisonRegister, kSpeculationPoisonRegister,
kJavaScriptCallCodeStartRegister);
__ ShiftRightArithImm(kSpeculationPoisonRegister, kSpeculationPoisonRegister,
kBitsPerPointer - 1);
__ notx(kSpeculationPoisonRegister, kSpeculationPoisonRegister);
}
// Assembles an instruction after register allocation, producing machine code. // Assembles an instruction after register allocation, producing machine code.
CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction( CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
Instruction* instr) { Instruction* instr) {
......
...@@ -1056,6 +1056,31 @@ void CodeGenerator::BailoutIfDeoptimized() { ...@@ -1056,6 +1056,31 @@ void CodeGenerator::BailoutIfDeoptimized() {
__ Jump(code, RelocInfo::CODE_TARGET, ne); __ Jump(code, RelocInfo::CODE_TARGET, ne);
} }
void CodeGenerator::GenerateSpeculationPoison() {
Register scratch = r1;
Label current_pc;
__ larl(scratch, &current_pc);
__ bind(&current_pc);
__ SubP(scratch, Operand(__ pc_offset()));
// Calculate a mask which has all bits set in the normal case, but has all
// bits cleared if we are speculatively executing the wrong PC.
// difference = (current - expected) | (expected - current)
// poison = ~(difference >> (kBitsPerPointer - 1))
__ LoadRR(kSpeculationPoisonRegister, scratch);
__ SubP(kSpeculationPoisonRegister, kSpeculationPoisonRegister,
kJavaScriptCallCodeStartRegister);
__ SubP(kJavaScriptCallCodeStartRegister, kJavaScriptCallCodeStartRegister,
scratch);
__ OrP(kSpeculationPoisonRegister, kSpeculationPoisonRegister,
kJavaScriptCallCodeStartRegister);
__ ShiftRightArithP(kSpeculationPoisonRegister, kSpeculationPoisonRegister,
Operand(kBitsPerPointer - 1));
__ NotP(kSpeculationPoisonRegister, kSpeculationPoisonRegister);
}
// Assembles an instruction after register allocation, producing machine code. // Assembles an instruction after register allocation, producing machine code.
CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction( CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
Instruction* instr) { Instruction* instr) {
......
...@@ -291,8 +291,7 @@ void InterpreterDispatchDescriptor::InitializePlatformSpecific( ...@@ -291,8 +291,7 @@ void InterpreterDispatchDescriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) { CallInterfaceDescriptorData* data) {
Register registers[] = { Register registers[] = {
kInterpreterAccumulatorRegister, kInterpreterBytecodeOffsetRegister, kInterpreterAccumulatorRegister, kInterpreterBytecodeOffsetRegister,
kInterpreterBytecodeArrayRegister, kInterpreterDispatchTableRegister, kInterpreterBytecodeArrayRegister, kInterpreterDispatchTableRegister};
kInterpreterTargetBytecodeRegister};
data->InitializePlatformSpecific(arraysize(registers), registers); data->InitializePlatformSpecific(arraysize(registers), registers);
} }
......
...@@ -15,22 +15,23 @@ namespace v8 { ...@@ -15,22 +15,23 @@ namespace v8 {
namespace internal { namespace internal {
// Give alias names to registers for calling conventions. // Give alias names to registers for calling conventions.
const Register kReturnRegister0 = r3; constexpr Register kReturnRegister0 = r3;
const Register kReturnRegister1 = r4; constexpr Register kReturnRegister1 = r4;
const Register kReturnRegister2 = r5; constexpr Register kReturnRegister2 = r5;
const Register kJSFunctionRegister = r4; constexpr Register kJSFunctionRegister = r4;
const Register kContextRegister = r30; constexpr Register kContextRegister = r30;
const Register kAllocateSizeRegister = r4; constexpr Register kAllocateSizeRegister = r4;
const Register kInterpreterAccumulatorRegister = r3; constexpr Register kSpeculationPoisonRegister = r14;
const Register kInterpreterBytecodeOffsetRegister = r15; constexpr Register kInterpreterAccumulatorRegister = r3;
const Register kInterpreterBytecodeArrayRegister = r16; constexpr Register kInterpreterBytecodeOffsetRegister = r15;
const Register kInterpreterDispatchTableRegister = r17; constexpr Register kInterpreterBytecodeArrayRegister = r16;
const Register kInterpreterTargetBytecodeRegister = r14; constexpr Register kInterpreterDispatchTableRegister = r17;
const Register kJavaScriptCallArgCountRegister = r3; constexpr Register kJavaScriptCallArgCountRegister = r3;
const Register kJavaScriptCallNewTargetRegister = r6; constexpr Register kJavaScriptCallNewTargetRegister = r6;
const Register kOffHeapTrampolineRegister = ip; constexpr Register kJavaScriptCallCodeStartRegister = r5;
const Register kRuntimeCallFunctionRegister = r4; constexpr Register kOffHeapTrampolineRegister = ip;
const Register kRuntimeCallArgCountRegister = r3; constexpr Register kRuntimeCallFunctionRegister = r4;
constexpr Register kRuntimeCallArgCountRegister = r3;
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// Static helper functions // Static helper functions
......
...@@ -285,8 +285,7 @@ void InterpreterDispatchDescriptor::InitializePlatformSpecific( ...@@ -285,8 +285,7 @@ void InterpreterDispatchDescriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) { CallInterfaceDescriptorData* data) {
Register registers[] = { Register registers[] = {
kInterpreterAccumulatorRegister, kInterpreterBytecodeOffsetRegister, kInterpreterAccumulatorRegister, kInterpreterBytecodeOffsetRegister,
kInterpreterBytecodeArrayRegister, kInterpreterDispatchTableRegister, kInterpreterBytecodeArrayRegister, kInterpreterDispatchTableRegister};
kInterpreterTargetBytecodeRegister};
data->InitializePlatformSpecific(arraysize(registers), registers); data->InitializePlatformSpecific(arraysize(registers), registers);
} }
......
...@@ -14,22 +14,23 @@ namespace v8 { ...@@ -14,22 +14,23 @@ namespace v8 {
namespace internal { namespace internal {
// Give alias names to registers for calling conventions. // Give alias names to registers for calling conventions.
const Register kReturnRegister0 = r2; constexpr Register kReturnRegister0 = r2;
const Register kReturnRegister1 = r3; constexpr Register kReturnRegister1 = r3;
const Register kReturnRegister2 = r4; constexpr Register kReturnRegister2 = r4;
const Register kJSFunctionRegister = r3; constexpr Register kJSFunctionRegister = r3;
const Register kContextRegister = r13; constexpr Register kContextRegister = r13;
const Register kAllocateSizeRegister = r3; constexpr Register kAllocateSizeRegister = r3;
const Register kInterpreterAccumulatorRegister = r2; constexpr Register kSpeculationPoisonRegister = r5;
const Register kInterpreterBytecodeOffsetRegister = r6; constexpr Register kInterpreterAccumulatorRegister = r2;
const Register kInterpreterBytecodeArrayRegister = r7; constexpr Register kInterpreterBytecodeOffsetRegister = r6;
const Register kInterpreterDispatchTableRegister = r8; constexpr Register kInterpreterBytecodeArrayRegister = r7;
const Register kInterpreterTargetBytecodeRegister = r5; constexpr Register kInterpreterDispatchTableRegister = r8;
const Register kJavaScriptCallArgCountRegister = r2; constexpr Register kJavaScriptCallArgCountRegister = r2;
const Register kJavaScriptCallNewTargetRegister = r5; constexpr Register kJavaScriptCallNewTargetRegister = r5;
const Register kOffHeapTrampolineRegister = ip; constexpr Register kJavaScriptCallCodeStartRegister = r4;
const Register kRuntimeCallFunctionRegister = r3; constexpr Register kOffHeapTrampolineRegister = ip;
const Register kRuntimeCallArgCountRegister = r2; constexpr Register kRuntimeCallFunctionRegister = r3;
constexpr Register kRuntimeCallArgCountRegister = r2;
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// Static helper functions // Static helper functions
......
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