Skip to content
Permalink
Browse files

8241438: Move IntelJccErratum mitigation code to platform-specific code

Reviewed-by: vlivanov, kvn
  • Loading branch information
fisk committed Apr 8, 2020
1 parent 6c1f8e1 commit 76a8557d0cf0c3be33ca3dcf9c9068072c563b85
@@ -1027,6 +1027,13 @@ class HandlerImpl {
}
};

class Node::PD {
public:
enum NodeFlags {
_last_flag = Node::_last_flag
};
};

bool is_CAS(int opcode, bool maybe_volatile);

// predicates controlling emit of ldr<x>/ldar<x> and associated dmb
@@ -1051,6 +1058,17 @@ source %{

// Derived RegMask with conditionally allocatable registers

void PhaseOutput::pd_perform_mach_node_analysis() {
}

int MachNode::pd_alignment_required() const {
return 1;
}

int MachNode::compute_padding(int current_offset) const {
return 0;
}

RegMask _ANY_REG32_mask;
RegMask _ANY_REG_mask;
RegMask _PTR_REG_mask;
@@ -116,6 +116,13 @@ class HandlerImpl {

};

class Node::PD {
public:
enum NodeFlags {
_last_flag = Node::_last_flag
};
};

%}

source %{
@@ -124,6 +131,16 @@ source %{
static FloatRegister reg_to_FloatRegister_object(int register_encoding);
static Register reg_to_register_object(int register_encoding);

void PhaseOutput::pd_perform_mach_node_analysis() {
}

int MachNode::pd_alignment_required() const {
return 1;
}

int MachNode::compute_padding(int current_offset) const {
return 0;
}

// ****************************************************************************

@@ -982,6 +982,17 @@ source_hpp %{

source %{

void PhaseOutput::pd_perform_mach_node_analysis() {
}

int MachNode::pd_alignment_required() const {
return 1;
}

int MachNode::compute_padding(int current_offset) const {
return 0;
}

// Should the Matcher clone shifts on addressing modes, expecting them
// to be subsumed into complex addressing expressions or compute them
// into registers?
@@ -2164,6 +2175,13 @@ class HandlerImpl {

};

class Node::PD {
public:
enum NodeFlags {
_last_flag = Node::_last_flag
};
};

%} // end source_hpp

source %{
@@ -605,6 +605,17 @@ static Register reg_to_register_object(int register_encoding);
// from the start of the call to the point where the return address
// will point.

void PhaseOutput::pd_perform_mach_node_analysis() {
}

int MachNode::pd_alignment_required() const {
return 1;
}

int MachNode::compute_padding(int current_offset) const {
return 0;
}

int MachCallStaticJavaNode::ret_addr_offset() {
if (_method) {
return 8;
@@ -1423,6 +1434,13 @@ class HandlerImpl {
}
};

class Node::PD {
public:
enum NodeFlags {
_last_flag = Node::_last_flag
};
};

%} // end source_hpp section

source %{
@@ -471,6 +471,13 @@ class HandlerImpl {
}
};

class Node::PD {
public:
enum NodeFlags {
_last_flag = Node::_last_flag
};
};

%}

source %{
@@ -483,6 +490,17 @@ static FloatRegister reg_to_SingleFloatRegister_object(int register_encoding);
static FloatRegister reg_to_DoubleFloatRegister_object(int register_encoding);
static Register reg_to_register_object(int register_encoding);

void PhaseOutput::pd_perform_mach_node_analysis() {
}

int MachNode::pd_alignment_required() const {
return 1;
}

int MachNode::compute_padding(int current_offset) const {
return 0;
}

// Used by the DFA in dfa_sparc.cpp.
// Check for being able to use a V9 branch-on-register. Requires a
// compare-vs-zero, equal/not-equal, of a value which was zero- or sign-
@@ -53,7 +53,7 @@ bool IntelJccErratum::is_jcc_erratum_branch(const Block* block, const MachNode*
}

int IntelJccErratum::jcc_erratum_taint_node(MachNode* node, PhaseRegAlloc* regalloc) {
node->add_flag(Node::Flag_intel_jcc_erratum);
node->add_flag(Node::PD::Flag_intel_jcc_erratum);
return node->size(regalloc);
}

@@ -99,7 +99,7 @@ int IntelJccErratum::compute_padding(uintptr_t current_offset, const MachNode* m
int jcc_size = mach->size(regalloc);
if (index_in_block < block->number_of_nodes() - 1) {
Node* next = block->get_node(index_in_block + 1);
if (next->is_Mach() && (next->as_Mach()->flags() & Node::Flag_intel_jcc_erratum)) {
if (next->is_Mach() && (next->as_Mach()->flags() & Node::PD::Flag_intel_jcc_erratum)) {
jcc_size += mach->size(regalloc);
}
}
@@ -1165,11 +1165,51 @@ class HandlerImpl {
#endif
};

class Node::PD {
public:
enum NodeFlags {
Flag_intel_jcc_erratum = Node::_last_flag << 1,
_last_flag = Flag_intel_jcc_erratum
};
};

%} // end source_hpp

source %{

#include "opto/addnode.hpp"
#include "c2_intelJccErratum_x86.hpp"

void PhaseOutput::pd_perform_mach_node_analysis() {
if (VM_Version::has_intel_jcc_erratum()) {
int extra_padding = IntelJccErratum::tag_affected_machnodes(C, C->cfg(), C->regalloc());
_buf_sizes._code += extra_padding;
}
}

int MachNode::pd_alignment_required() const {
PhaseOutput* output = Compile::current()->output();
Block* block = output->block();
int index = output->index();
if (VM_Version::has_intel_jcc_erratum() && IntelJccErratum::is_jcc_erratum_branch(block, this, index)) {
// Conservatively add worst case padding. We assume that relocInfo::addr_unit() is 1 on x86.
return IntelJccErratum::largest_jcc_size() + 1;
} else {
return 1;
}
}

int MachNode::compute_padding(int current_offset) const {
if (flags() & Node::PD::Flag_intel_jcc_erratum) {
Compile* C = Compile::current();
PhaseOutput* output = C->output();
Block* block = output->block();
int index = output->index();
return IntelJccErratum::compute_padding(current_offset, this, block, index, C->regalloc());
} else {
return 0;
}
}

// Emit exception handler code.
// Stuff framesize into a register and call a VM stub routine.
@@ -286,11 +286,12 @@ class MachNode : public Node {

// Return the alignment required (in units of relocInfo::addr_unit())
// for this instruction (must be a power of 2)
virtual int alignment_required() const { return 1; }
int pd_alignment_required() const;
virtual int alignment_required() const { return pd_alignment_required(); }

// Return the padding (in bytes) to be emitted before this
// instruction to properly align it.
virtual int compute_padding(int current_offset) const { return 0; }
virtual int compute_padding(int current_offset) const;

// Return number of relocatable values contained in this instruction
virtual int reloc() const { return 0; }
@@ -28,6 +28,7 @@
#include "libadt/vectset.hpp"
#include "memory/allocation.inline.hpp"
#include "memory/resourceArea.hpp"
#include "opto/ad.hpp"
#include "opto/castnode.hpp"
#include "opto/cfgnode.hpp"
#include "opto/connode.hpp"
@@ -1033,7 +1034,12 @@ bool Node::verify_jvms(const JVMState* using_jvms) const {
//------------------------------init_NodeProperty------------------------------
void Node::init_NodeProperty() {
assert(_max_classes <= max_jushort, "too many NodeProperty classes");
assert(_max_flags <= max_jushort, "too many NodeProperty flags");
assert(max_flags() <= max_jushort, "too many NodeProperty flags");
}

//-----------------------------max_flags---------------------------------------
juint Node::max_flags() {
return (PD::_last_flag << 1) - 1; // allow flags combination
}
#endif

@@ -740,25 +740,28 @@ class Node {
Flag_is_scheduled = Flag_is_reduction << 1,
Flag_has_vector_mask_set = Flag_is_scheduled << 1,
Flag_is_expensive = Flag_has_vector_mask_set << 1,
Flag_intel_jcc_erratum = Flag_is_expensive << 1,
_max_flags = (Flag_intel_jcc_erratum << 1) - 1 // allow flags combination
_last_flag = Flag_is_expensive
};

class PD;

private:
jushort _class_id;
jushort _flags;

static juint max_flags();

protected:
// These methods should be called from constructors only.
void init_class_id(jushort c) {
_class_id = c; // cast out const
}
void init_flags(uint fl) {
assert(fl <= _max_flags, "invalid node flag");
assert(fl <= max_flags(), "invalid node flag");
_flags |= fl;
}
void clear_flag(uint fl) {
assert(fl <= _max_flags, "invalid node flag");
assert(fl <= max_flags(), "invalid node flag");
_flags &= ~fl;
}

0 comments on commit 76a8557

Please sign in to comment.