Permalink
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Browse files
8241438: Move IntelJccErratum mitigation code to platform-specific code
Reviewed-by: vlivanov, kvn
- Loading branch information
|
@@ -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; |
|
|
} |
|
|
|
|
|
Oops, something went wrong.