Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
A prototype for intrinsifying Math.addExact(int, int), version 3
diff -r 751bd303aa45 src/cpu/x86/vm/x86_64.ad
--- a/src/cpu/x86/vm/x86_64.ad Tue Jun 26 09:06:16 2012 -0700
+++ b/src/cpu/x86/vm/x86_64.ad Wed Jun 27 21:02:11 2012 +0800
@@ -1674,6 +1674,16 @@
return LONG_RDX_REG_mask();
}
+// Register for AddI projection of checkedAddI
+RegMask Matcher::checkedAddI_sum_proj_mask() {
+ return INT_RAX_REG_mask();
+}
+
+// Register for conditions projection
+RegMask Matcher::overflow_proj_mask() {
+ return INT_FLAGS_mask();
+}
+
const RegMask Matcher::method_handle_invoke_SP_save_mask() {
return PTR_RBP_REG_mask();
}
@@ -4173,6 +4183,8 @@
greater_equal(0xD, "ge");
less_equal(0xE, "le");
greater(0xF, "g");
+ overflow(0x0, "o");
+ no_overflow(0x1, "no");
%}
%}
@@ -4191,6 +4203,8 @@
greater_equal(0x3, "nb");
less_equal(0x6, "be");
greater(0x7, "nbe");
+ overflow(0x0, "o");
+ no_overflow(0x1, "no");
%}
%}
@@ -4210,6 +4224,8 @@
greater_equal(0x3, "nb");
less_equal(0x6, "be");
greater(0x7, "nbe");
+ overflow(0x0, "o");
+ no_overflow(0x1, "no");
%}
%}
@@ -4227,6 +4243,8 @@
greater_equal(0x3, "nb");
less_equal(0x6, "be");
greater(0x7, "nbe");
+ overflow(0x0, "o");
+ no_overflow(0x1, "no");
%}
%}
@@ -7673,6 +7691,19 @@
ins_pipe(ialu_reg_reg_alu0);
%}
+// Integer addition with overflow checking
+instruct checkedAddI_rReg(rax_RegI rax, rRegI src, rFlagsReg cr)
+%{
+ match(CheckedAddI rax src);
+ effect(DEF cr);
+
+ format %{ "addl $rax, $src\t# int with overflow check" %}
+ ins_encode %{
+ __ addl($rax$$Register, $src$$Register);
+ %}
+ ins_pipe(ialu_reg_reg);
+%}
+
// Integer DIVMOD with Register, both quotient and mod results
instruct divModI_rReg_divmod(rax_RegI rax, rdx_RegI rdx, no_rax_rdx_RegI div,
rFlagsReg cr)
diff -r 751bd303aa45 src/share/vm/adlc/adlparse.cpp
--- a/src/share/vm/adlc/adlparse.cpp Tue Jun 26 09:06:16 2012 -0700
+++ b/src/share/vm/adlc/adlparse.cpp Wed Jun 27 21:02:11 2012 +0800
@@ -3388,12 +3388,16 @@
char *greater_equal;
char *less_equal;
char *greater;
+ char *overflow;
+ char *no_overflow;
const char *equal_format = "eq";
const char *not_equal_format = "ne";
const char *less_format = "lt";
const char *greater_equal_format = "ge";
const char *less_equal_format = "le";
const char *greater_format = "gt";
+ const char *overflow_format = "ov";
+ const char *no_overflow_format = "no";
if (_curchar != '%') {
parse_err(SYNERR, "Missing '%{' for 'cond_interface' block.\n");
@@ -3430,6 +3434,12 @@
else if ( strcmp(field,"greater") == 0 ) {
greater = interface_field_parse(&greater_format);
}
+ else if ( strcmp(field,"overflow") == 0 ) {
+ overflow = interface_field_parse(&overflow_format);
+ }
+ else if ( strcmp(field,"no_overflow") == 0 ) {
+ no_overflow = interface_field_parse(&no_overflow_format);
+ }
else {
parse_err(SYNERR, "Expected keyword, base|index|scale|disp, or '%}' ending interface.\n");
return NULL;
@@ -3448,7 +3458,9 @@
less, less_format,
greater_equal, greater_equal_format,
less_equal, less_equal_format,
- greater, greater_format);
+ greater, greater_format,
+ overflow, overflow_format,
+ no_overflow, no_overflow_format);
return inter;
}
diff -r 751bd303aa45 src/share/vm/adlc/formssel.cpp
--- a/src/share/vm/adlc/formssel.cpp Tue Jun 26 09:06:16 2012 -0700
+++ b/src/share/vm/adlc/formssel.cpp Wed Jun 27 21:02:11 2012 +0800
@@ -2694,14 +2694,18 @@
const char* less, const char* less_format,
const char* greater_equal, const char* greater_equal_format,
const char* less_equal, const char* less_equal_format,
- const char* greater, const char* greater_format)
+ const char* greater, const char* greater_format,
+ const char* overflow, const char* overflow_format,
+ const char* no_overflow, const char* no_overflow_format)
: Interface("COND_INTER"),
_equal(equal), _equal_format(equal_format),
_not_equal(not_equal), _not_equal_format(not_equal_format),
_less(less), _less_format(less_format),
_greater_equal(greater_equal), _greater_equal_format(greater_equal_format),
_less_equal(less_equal), _less_equal_format(less_equal_format),
- _greater(greater), _greater_format(greater_format) {
+ _greater(greater), _greater_format(greater_format),
+ _overflow(overflow), _overflow_format(overflow_format),
+ _no_overflow(no_overflow), _no_overflow_format(no_overflow_format) {
}
CondInterface::~CondInterface() {
// not owner of any character arrays
@@ -2720,6 +2724,8 @@
if ( _greater_equal != NULL ) fprintf(fp," greater_equal == %s\n", _greater_equal);
if ( _less_equal != NULL ) fprintf(fp," less_equal == %s\n", _less_equal);
if ( _greater != NULL ) fprintf(fp," greater == %s\n", _greater);
+ if ( _overflow != NULL ) fprintf(fp," overflow == %s\n", _overflow);
+ if ( _no_overflow != NULL ) fprintf(fp," no_overflow == %s\n", _no_overflow);
// fprintf(fp,"\n");
}
diff -r 751bd303aa45 src/share/vm/adlc/formssel.hpp
--- a/src/share/vm/adlc/formssel.hpp Tue Jun 26 09:06:16 2012 -0700
+++ b/src/share/vm/adlc/formssel.hpp Wed Jun 27 21:02:11 2012 +0800
@@ -786,7 +786,7 @@
//------------------------------CondInterface----------------------------------
class CondInterface : public Interface {
private:
-
+// TODO fix comments of COND_INTER in *.ad files
public:
const char *_equal;
const char *_not_equal;
@@ -794,12 +794,16 @@
const char *_greater_equal;
const char *_less_equal;
const char *_greater;
+ const char *_overflow;
+ const char *_no_overflow;
const char *_equal_format;
const char *_not_equal_format;
const char *_less_format;
const char *_greater_equal_format;
const char *_less_equal_format;
const char *_greater_format;
+ const char *_overflow_format;
+ const char *_no_overflow_format;
// Public Methods
CondInterface(const char* equal, const char* equal_format,
@@ -807,7 +811,9 @@
const char* less, const char* less_format,
const char* greater_equal, const char* greater_equal_format,
const char* less_equal, const char* less_equal_format,
- const char* greater, const char* greater_format);
+ const char* greater, const char* greater_format,
+ const char* overflow, const char* overflow_format,
+ const char* no_overflow, const char* no_overflow_format);
~CondInterface();
void dump();
diff -r 751bd303aa45 src/share/vm/adlc/output_h.cpp
--- a/src/share/vm/adlc/output_h.cpp Tue Jun 26 09:06:16 2012 -0700
+++ b/src/share/vm/adlc/output_h.cpp Wed Jun 27 21:02:11 2012 +0800
@@ -364,6 +364,8 @@
fprintf(fp, " else if( _c%d == BoolTest::ge ) st->print(\"%s\");\n",i,cond->_greater_equal_format);
fprintf(fp, " else if( _c%d == BoolTest::lt ) st->print(\"%s\");\n",i,cond->_less_format);
fprintf(fp, " else if( _c%d == BoolTest::gt ) st->print(\"%s\");\n",i,cond->_greater_format);
+ fprintf(fp, " else if( _c%d == BoolTest::ov ) st->print(\"%s\");\n",i,cond->_overflow_format);
+ fprintf(fp, " else if( _c%d == BoolTest::no ) st->print(\"%s\");\n",i,cond->_no_overflow_format);
}
// Output code that dumps constant values, increment "i" if type is constant
@@ -1178,6 +1180,8 @@
fprintf(fp," case BoolTest::ne : return not_equal();\n");
fprintf(fp," case BoolTest::le : return less_equal();\n");
fprintf(fp," case BoolTest::ge : return greater_equal();\n");
+ fprintf(fp," case BoolTest::ov : return overflow();\n");
+ fprintf(fp," case BoolTest::no : return no_overflow();\n");
fprintf(fp," default : ShouldNotReachHere(); return 0;\n");
fprintf(fp," }\n");
fprintf(fp," };\n");
@@ -1343,6 +1347,14 @@
if( greater != NULL ) {
define_oper_interface(fp, *oper, _globalNames, "greater", greater);
}
+ const char *overflow = cInterface->_overflow;
+ if( overflow != NULL ) {
+ define_oper_interface(fp, *oper, _globalNames, "overflow", overflow);
+ }
+ const char *no_overflow = cInterface->_no_overflow;
+ if( no_overflow != NULL ) {
+ define_oper_interface(fp, *oper, _globalNames, "no_overflow", no_overflow);
+ }
} // end Conditional Interface
// Check if it is a Constant Interface
else if (oper->_interface->is_ConstInterface() != NULL ) {
diff -r 751bd303aa45 src/share/vm/opto/classes.hpp
--- a/src/share/vm/opto/classes.hpp Tue Jun 26 09:06:16 2012 -0700
+++ b/src/share/vm/opto/classes.hpp Wed Jun 27 21:02:11 2012 +0800
@@ -60,6 +60,8 @@
macro(Catch)
macro(CatchProj)
macro(CheckCastPP)
+macro(CheckedAdd)
+macro(CheckedAddI)
macro(ClearArray)
macro(ConstraintCast)
macro(CMoveD)
@@ -68,6 +70,7 @@
macro(CMoveL)
macro(CMoveP)
macro(CMoveN)
+macro(CmpAddI)
macro(CmpN)
macro(CmpD)
macro(CmpD3)
diff -r 751bd303aa45 src/share/vm/opto/compile.cpp
--- a/src/share/vm/opto/compile.cpp Tue Jun 26 09:06:16 2012 -0700
+++ b/src/share/vm/opto/compile.cpp Wed Jun 27 21:02:11 2012 +0800
@@ -2591,6 +2591,16 @@
}
break;
+ case Op_CmpAddI: {
+ Node* sum = n->find_similar(Op_AddI);
+ assert(sum != NULL, "should find corresponding AddI");
+ Compile* C = Compile::current();
+ CheckedAddINode* chkadd = CheckedAddINode::make(C, n);
+ sum->subsume_by(chkadd->sum_proj());
+ n->subsume_by(chkadd->overflow_proj());
+ break;
+ }
+
case Op_LoadVector:
case Op_StoreVector:
break;
diff -r 751bd303aa45 src/share/vm/opto/matcher.hpp
--- a/src/share/vm/opto/matcher.hpp Tue Jun 26 09:06:16 2012 -0700
+++ b/src/share/vm/opto/matcher.hpp Wed Jun 27 21:02:11 2012 +0800
@@ -317,6 +317,12 @@
// Register for MODL projection of divmodL
static RegMask modL_proj_mask();
+ // Register for AddI projection of checkedAddI
+ static RegMask checkedAddI_sum_proj_mask();
+
+ // Register for conditions projection
+ static RegMask overflow_proj_mask();
+
// Use hardware DIV instruction when it is faster than
// a code which use multiply for division by constant.
static bool use_asm_for_ldiv_by_con( jlong divisor );
diff -r 751bd303aa45 src/share/vm/opto/subnode.cpp
--- a/src/share/vm/opto/subnode.cpp Tue Jun 26 09:06:16 2012 -0700
+++ b/src/share/vm/opto/subnode.cpp Wed Jun 27 21:02:11 2012 +0800
@@ -1035,6 +1035,45 @@
}
+//==============================================================================
+
+const Type* CmpAddINode::Value(PhaseTransform *phase) const {
+ return TypeInt::CC; // just return the worst case for now
+}
+
+CheckedAddNode::CheckedAddNode(Node* c, Node* in1, Node* in2) : MultiNode(3) {
+ init_req(0, c);
+ init_req(1, in1);
+ init_req(2, in2);
+}
+
+//-------------------------------make-------------------------------------------
+CheckedAddINode* CheckedAddINode::make(Compile* C, Node* cmpadd) {
+ Node* n = cmpadd;
+ assert(n->Opcode() == Op_CmpAddI, "only CmpAddI accepted");
+
+ CheckedAddINode* chkadd = new (C, 3) CheckedAddINode(n->in(0), n->in(1), n->in(2));
+ Node* sproj = new (C, 1) ProjNode(chkadd, CheckedAddNode::sum_proj_num);
+ Node* oproj = new (C, 1) FlagsProjNode(chkadd, CheckedAddNode::overflow_proj_num);
+ return chkadd;
+}
+
+//------------------------------match------------------------------------------
+// return result(s) along with their RegMask info
+Node* CheckedAddINode::match(const ProjNode* proj, const Matcher* match) {
+ uint ideal_reg = proj->ideal_reg();
+ RegMask rm;
+ if (proj->_con == sum_proj_num) {
+ rm = match->checkedAddI_sum_proj_mask();
+ } else {
+ assert(proj->_con == overflow_proj_num, "must be sum or overflow projection");
+ assert(ideal_reg == Op_RegFlags, "sanity");
+ rm = match->overflow_proj_mask();
+ }
+ return new (match->C, 1) MachProjNode(this, proj->_con, rm, ideal_reg);
+}
+
+
//=============================================================================
//------------------------------cc2logical-------------------------------------
// Convert a condition code type to a logical type
@@ -1065,7 +1104,7 @@
// Print special per-node info
#ifndef PRODUCT
void BoolTest::dump_on(outputStream *st) const {
- const char *msg[] = {"eq","gt","??","lt","ne","le","??","ge"};
+ const char *msg[] = {"eq","gt","ov","lt","ne","le","no","ge","??"};
st->print(msg[_test]);
}
#endif
@@ -1218,6 +1257,32 @@
return new (phase->C, 2) BoolNode( ncmp, _test.commute() );
}
+ // Consolidate overflow checking for integer addition into a CmpAddI node.
+ // Match the following pattern:
+ // Bool(CmpI(AndI(XorI(x, AddI(x, y)), XorI(y, AddI(x, y))), ConI(0)), [lt])
+ if ( Matcher::has_match_rule(Op_CheckedAddI) &&
+ cop == Op_CmpI &&
+ cmp1_op == Op_AndI &&
+ cmp2_type == TypeInt::ZERO &&
+ (_test._test == BoolTest::lt) ) {
+ Node* xor1 = cmp1->in(1);
+ Node* xor2 = cmp1->in(2);
+ if (xor1->Opcode() == Op_XorI &&
+ xor2->Opcode() == Op_XorI) {
+ Node* x = xor1->in(1);
+ Node* y = xor2->in(1);
+ Node* sum = xor1->in(2);
+ if (sum->Opcode() == Op_AddI &&
+ xor2->in(2) == sum &&
+ ((sum->in(1) == x && sum->in(2) == y) ||
+ (sum->in(2) == x && sum->in(1) == y)) ) {
+ // found the overflow checking pattern
+ Node* cmpadd = phase->transform(new (phase->C, 3) CmpAddINode(sum->in(1), sum->in(2)));
+ return new (phase->C, 2) BoolNode(cmpadd, BoolTest::ov);
+ }
+ }
+ }
+
// The transformation below is not valid for either signed or unsigned
// comparisons due to wraparound concerns at MAX_VALUE and MIN_VALUE.
// This transformation can be resurrected when we are able to
diff -r 751bd303aa45 src/share/vm/opto/subnode.hpp
--- a/src/share/vm/opto/subnode.hpp Tue Jun 26 09:06:16 2012 -0700
+++ b/src/share/vm/opto/subnode.hpp Wed Jun 27 21:02:11 2012 +0800
@@ -257,21 +257,78 @@
};
+//------------------------------CmpAddINode-------------------------------------
+// Check the sum of two values for overflow, returning condition codes.
+class CmpAddINode : public CmpINode {
+public:
+ CmpAddINode(Node* in1, Node* in2) : CmpINode(in1, in2) {}
+ virtual int Opcode() const;
+ virtual Node* Ideal(PhaseGVN* phase, bool can_reshape) { return NULL; }
+ virtual const Type* Value(PhaseTransform* phase) const;
+};
+
+class FlagsProjNode : public ProjNode {
+public:
+ FlagsProjNode(Node* src, uint con) : ProjNode(src, con) {}
+
+ virtual bool is_CFG() const { return false; }
+ virtual const Type* bottom_type() const { return TypeInt::CC; }
+ virtual uint ideal_reg() const { return Op_RegFlags; }
+};
+
+//-----------------------------CheckedAddNode-----------------------------------
+// Addition with overflow condition
+class CheckedAddNode : public MultiNode {
+protected:
+ CheckedAddNode(Node* c, Node* in1, Node* in2);
+public:
+ enum {
+ sum_proj_num = 0, // sum
+ overflow_proj_num = 1 // overflow condition
+ };
+ virtual int Opcode() const;
+ virtual Node* Identity(PhaseTransform* phase) { return this; }
+ virtual Node* Ideal(PhaseGVN* phase, bool can_reshape) { return NULL; }
+ virtual const Type* Value(PhaseTransform* phase) const { return bottom_type(); }
+ virtual uint hash() const { return Node::hash(); }
+ virtual bool is_CFG() const { return false; }
+ virtual uint ideal_reg() const { return NotAMachineReg; }
+
+ ProjNode* sum_proj() { return proj_out(sum_proj_num); }
+ ProjNode* overflow_proj() { return proj_out(overflow_proj_num); }
+};
+
+//-----------------------------CheckedAddINode----------------------------------
+// Integer addition with overflow condition
+class CheckedAddINode : public CheckedAddNode {
+public:
+ CheckedAddINode(Node* c, Node* in1, Node* in2) : CheckedAddNode(c, in1, in2) {}
+ virtual int Opcode() const;
+ virtual const Type* bottom_type() const { return TypeTuple::INT_CC_PAIR; }
+ virtual Node* match( const ProjNode *proj, const Matcher *m );
+
+ static CheckedAddINode* make(Compile* C, Node* cmpadd);
+};
+
+
//------------------------------BoolTest---------------------------------------
// Convert condition codes to a boolean test value (0 or -1).
// We pick the values as 3 bits; the low order 2 bits we compare against the
// condition codes, the high bit flips the sense of the result.
struct BoolTest VALUE_OBJ_CLASS_SPEC {
- enum mask { eq = 0, ne = 4, le = 5, ge = 7, lt = 3, gt = 1, illegal = 8 };
+ enum mask { eq = 0, ne = 4, le = 5, ge = 7, lt = 3, gt = 1, ov = 2, no = 6, illegal = 8 };
mask _test;
BoolTest( mask btm ) : _test(btm) {}
const Type *cc2logical( const Type *CC ) const;
// Commute the test. I use a small table lookup. The table is created as
// a simple char array where each element is the ASCII version of a 'mask'
// enum from above.
- mask commute( ) const { return mask("038147858"[_test]-'0'); }
+ mask commute( ) const { return mask("036147258"[_test]-'0'); }
mask negate( ) const { return mask(_test^4); }
- bool is_canonical( ) const { return (_test == BoolTest::ne || _test == BoolTest::lt || _test == BoolTest::le); }
+ bool is_canonical( ) const { return (_test == BoolTest::ne ||
+ _test == BoolTest::lt ||
+ _test == BoolTest::le ||
+ _test == BoolTest::ov); }
#ifndef PRODUCT
void dump_on(outputStream *st) const;
#endif
diff -r 751bd303aa45 src/share/vm/opto/type.cpp
--- a/src/share/vm/opto/type.cpp Tue Jun 26 09:06:16 2012 -0700
+++ b/src/share/vm/opto/type.cpp Wed Jun 27 21:02:11 2012 +0800
@@ -386,6 +386,11 @@
longpair[1] = TypeLong::LONG;
TypeTuple::LONG_PAIR = TypeTuple::make(2, longpair);
+ const Type **int_cc = TypeTuple::fields(2);
+ int_cc[0] = TypeInt::INT;
+ int_cc[1] = TypeInt::CC;
+ TypeTuple::INT_CC_PAIR = TypeTuple::make(2, int_cc);
+
_const_basic_type[T_NARROWOOP] = TypeNarrowOop::BOTTOM;
_const_basic_type[T_BOOLEAN] = TypeInt::BOOL;
_const_basic_type[T_CHAR] = TypeInt::CHAR;
@@ -1618,6 +1623,7 @@
const TypeTuple *TypeTuple::START_I2C;
const TypeTuple *TypeTuple::INT_PAIR;
const TypeTuple *TypeTuple::LONG_PAIR;
+const TypeTuple *TypeTuple::INT_CC_PAIR;
//------------------------------make-------------------------------------------
diff -r 751bd303aa45 src/share/vm/opto/type.hpp
--- a/src/share/vm/opto/type.hpp Tue Jun 26 09:06:16 2012 -0700
+++ b/src/share/vm/opto/type.hpp Wed Jun 27 21:02:11 2012 +0800
@@ -549,6 +549,7 @@
static const TypeTuple *START_I2C;
static const TypeTuple *INT_PAIR;
static const TypeTuple *LONG_PAIR;
+ static const TypeTuple *INT_CC_PAIR;
#ifndef PRODUCT
virtual void dump2( Dict &d, uint, outputStream *st ) const; // Specialized per-Type dumping
#endif
diff -r 751bd303aa45 src/share/vm/runtime/vmStructs.cpp
--- a/src/share/vm/runtime/vmStructs.cpp Tue Jun 26 09:06:16 2012 -0700
+++ b/src/share/vm/runtime/vmStructs.cpp Wed Jun 27 21:02:11 2012 +0800
@@ -1922,6 +1922,10 @@
declare_c2_type(CmpF3Node, CmpFNode) \
declare_c2_type(CmpDNode, CmpNode) \
declare_c2_type(CmpD3Node, CmpDNode) \
+ declare_c2_type(CmpAddINode, CmpINode) \
+ declare_c2_type(CheckedAddNode, MultiNode) \
+ declare_c2_type(CheckedAddINode, CheckedAddNode) \
+ declare_c2_type(FlagsProjNode, ProjNode) \
declare_c2_type(BoolNode, Node) \
declare_c2_type(AbsNode, Node) \
declare_c2_type(AbsINode, AbsNode) \
{method}
- klass: {other class}
- this oop: 0x000000060424c940
- method holder: 'FiboSample'
- constants: 0x000000060424c2a0 constant pool [93] for 'FiboSample' cache=0x000000060424d7b8
- access: 0x8100000a private static
- name: 'fibo'
- signature: '(I)I'
- max stack: 4
- max locals: 8
- size of params: 1
- method size: 16
- vtable index: -2
- i2i entry: 0x00002aaaab3531a0
- adapter: 0x000000000b369cd8
- compiled entry 0x00002aaaab40a830
- code size: 115
- code start: 0x000000060424c810
- code end (excl): 0x000000060424c883
- method data: 0x000000060424e308
- checked ex length: 1
- checked ex start: 0x000000060424c93c
- linenumber start: 0x000000060424c883
- localvar length: 12
- localvar start: 0x000000060424c8aa
#
# int ( int )
#
#r018 rsi : parm 0: int
# -- Old rsp -- Framesize: 48 --
#r191 rsp+44: in_preserve
#r190 rsp+40: return address
#r189 rsp+36: in_preserve
#r188 rsp+32: saved fp register
#r187 rsp+28: pad2, stack alignment
#r186 rsp+24: pad2, stack alignment
#r185 rsp+20: Fixed slot 1
#r184 rsp+16: Fixed slot 0
#r195 rsp+12: spill
#r194 rsp+ 8: spill
#r193 rsp+ 4: spill
#r192 rsp+ 0: spill
#
abababab N1: # B1 <- B30 B31 B14 B32 B17 Freq: 1
abababab
000 B1: # B13 B2 <- BLOCK HEAD IS JUNK Freq: 1
000 # stack bang
pushq rbp # Save rbp
subq rsp, #32 # Create frame
00c movl [rsp + #0], RSI # spill
00f cmpl RSI, #2
012 jl B13 P=0.500000 C=-1.000000
012
018 B2: # B25 B3 <- B1 Freq: 0.5
018 decl RSI # int
nop # 1 bytes pad for loops and calls
01b call,static FiboSample::fibo
# FiboSample::fibo @ bci:10 L[0]=rsp + #0 L[1]=_ L[2]=_ L[3]=_ L[4]=_ L[5]=_ L[6]=_ L[7]=_
# OopMap{off=32}
020
020 B3: # B4 <- B2 Freq: 0.49999
# Block is sole successor of call
020 movl [rsp + #4], RAX # spill
020
024 B4: # B21 B5 <- B27 B3 Freq: 0.499994
024 movl RSI, [rsp + #0] # spill
027 addl RSI, #-2 # int
nop # 1 bytes pad for loops and calls
02b call,static FiboSample::fibo
# FiboSample::fibo @ bci:30 L[0]=_ L[1]=rsp + #4 L[2]=#NULL L[3]=_ L[4]=_ L[5]=_ L[6]=_ L[7]=_
# OopMap{off=48}
030
030 B5: # B6 <- B4 Freq: 0.499984
# Block is sole successor of call
030 movl RBP, RAX # spill
030
032 B6: # B14 B7 <- B23 B5 Freq: 0.499989
032 movl RAX, [rsp + #4] # spill
036 addl RAX, RBP # int with overflow check
038 jno,us B14 P=0.500000 C=-1.000000
038
03a B7: # B15 B8 <- B6 Freq: 0.249994
03a # TLS is in R15
03a movq RAX, [R15 + #112 (8-bit)] # ptr
03e movq R10, RAX # spill
041 addq R10, #32 # ptr
045 cmpq R10, [R15 + #128 (32-bit)] # raw ptr
04c jnb,us B15 P=0.000100 C=-1.000000
04c
04e B8: # B9 <- B7 Freq: 0.249969
04e movq [R15 + #112 (8-bit)], R10 # ptr
052 PREFETCHNTA [R10 + #192 (32-bit)] # Prefetch allocation to non-temporal cache for write
05a movl R10, narrowoop: precise klass java/lang/ArithmeticException: 0x000000000b50ac08:Constant:exact * # compressed ptr
060 movq R10, [R12 + R10 << 3 + #176] (compressed oop addressing) # ptr
068 movq [RAX], R10 # ptr
06b movl [RAX + #8 (8-bit)], narrowoop: precise klass java/lang/ArithmeticException: 0x000000000b50ac08:Constant:exact * # compressed ptr
072 movl [RAX + #12 (8-bit)], R12 # int (R12_heapbase==0)
076 movq [RAX + #16 (8-bit)], R12 # long (R12_heapbase==0)
07a movq [RAX + #24 (8-bit)], R12 # long (R12_heapbase==0)
07a
07e B9: # B19 B10 <- B16 B8 Freq: 0.249994
07e
07e MEMBAR-storestore (empty encoding)
07e movq RSI, RAX # spill
081 # checkcastPP of RSI
081 movq RDX, java/lang/String:exact * # ptr
08b movq [rsp + #8], RSI # spill
nop # 3 bytes pad for loops and calls
093 call,static java.lang.ArithmeticException::<init>
# java.lang.Math::addExact @ bci:20 L[0]=_ L[1]=_ L[2]=_ STK[0]=rsp + #8
# FiboSample::fibo @ bci:62 L[0]=_ L[1]=rsp + #4 L[2]=_ L[3]=RBP L[4]=_ L[5]=_ L[6]=_ L[7]=_
# OopMap{[8]=Oop off=152}
098
098 B10: # B29 B11 <- B19 B9 Freq: 0.249992
098 movl RSI, [rsp + #4] # spill
09c movl RDX, RBP # spill
nop # 1 bytes pad for loops and calls
09f call,static FiboSample::overflowedAdd
# FiboSample::fibo @ bci:77 L[0]=_ L[1]=_ L[2]=_ L[3]=_ L[4]=_ L[5]=_ L[6]=_ L[7]=_
# OopMap{off=164}
0a4
0a4 B11: # B17 B12 <- B10 Freq: 0.249987
# Block is sole successor of call
0a4 testq RAX, RAX # ptr
0a7 jne,s B17 P=0.000001 C=-1.000000
0a7
0a9 B12: # B14 <- B11 Freq: 0.249986
0a9 xorl RAX, RAX # int
0ab jmp,s B14
0ab
0ad B13: # B14 <- B1 Freq: 0.5
0ad movl RAX, #1 # int
0ad
0b2 B14: # N1 <- B13 B6 B12 Freq: 0.999981
0b2 addq rsp, 32 # Destroy frame
popq rbp
testl rax, [rip + #offset_to_poll_page] # Safepoint: poll for GC
0bd ret
0bd
0be B15: # B18 B16 <- B7 Freq: 2.50036e-05
0be movq RSI, precise klass java/lang/ArithmeticException: 0x000000000b50ac08:Constant:exact * # ptr
nop # 3 bytes pad for loops and calls
0cb call,static wrapper for: _new_instance_Java
# java.lang.Math::addExact @ bci:14 L[0]=_ L[1]=_ L[2]=_
# FiboSample::fibo @ bci:62 L[0]=_ L[1]=rsp + #4 L[2]=_ L[3]=RBP L[4]=_ L[5]=_ L[6]=_ L[7]=_
# OopMap{off=208}
0d0
0d0 B16: # B9 <- B15 Freq: 2.50031e-05
# Block is sole successor of call
0d0 jmp,s B9
0d0
0d2 B17: # N1 <- B11 Freq: 2.49987e-07
0d2 movl RSI, #-20 # int
0d7 movq RBP, RAX # spill
nop # 1 bytes pad for loops and calls
0db call,static wrapper for: uncommon_trap(reason='null_assert' action='make_not_entrant')
# FiboSample::fibo @ bci:80 L[0]=_ L[1]=_ L[2]=_ L[3]=_ L[4]=_ L[5]=_ L[6]=_ L[7]=_ STK[0]=RBP
# OopMap{rbp=Oop off=224}
0e0 int3 # ShouldNotReachHere
0e0
0ed B18: # B30 <- B15 Freq: 2.50036e-10
0ed # exception oop is in rax; no code emitted
0ed movq RSI, RAX # spill
0f0 jmp,s B30
0f0
0f2 B19: # B10 B20 <- B9 Freq: 2.49994e-06
0f2 # exception oop is in rax; no code emitted
0f2 movl R11, [RAX + #8 (8-bit)] # compressed klass ptr
0f6 cmpl R11, narrowoop: precise klass java/lang/ArithmeticException: 0x000000000b50ac08:Constant:exact * # compressed ptr
0fd je,us B10 P=0.900000 C=-1.000000
0fd
0ff B20: # B30 <- B19 Freq: 2.49995e-07
0ff movq RSI, RAX # spill
102 jmp,s B30
102
104 B21: # B24 B22 <- B4 Freq: 4.99994e-06
104 # exception oop is in rax; no code emitted
104 movl R11, [RAX + #8 (8-bit)] # compressed klass ptr
108 cmpl R11, narrowoop: precise klass FiboSample$ControlFlowException: 0x000000000b508428:Constant:exact * # compressed ptr
10f jne,us B24 P=0.100000 C=-1.000000
10f
111 B22: # B32 B23 <- B21 Freq: 4.49995e-06
111 # checkcastPP of RAX
111 movl RBP, [RAX + #32 (8-bit)] # compressed ptr ! Field FiboSample$ControlFlowException.value
114 testl RBP, RBP # compressed ptr
116 jne,s B32 P=0.000001 C=-1.000000
116
118 B23: # B6 <- B22 Freq: 4.49995e-06
118 xorl RBP, RBP # int
11a jmp B6
11a
11f B24: # B30 <- B21 Freq: 4.99995e-07
11f movq RSI, RAX # spill
122 jmp,s B30
122
124 B25: # B28 B26 <- B2 Freq: 5e-06
124 # exception oop is in rax; no code emitted
124 movl R11, [RAX + #8 (8-bit)] # compressed klass ptr
128 cmpl R11, narrowoop: precise klass FiboSample$ControlFlowException: 0x000000000b508428:Constant:exact * # compressed ptr
12f jne,us B28 P=0.100000 C=-1.000000
12f
131 B26: # B31 B27 <- B25 Freq: 4.5e-06
131 # checkcastPP of RAX
131 movl RBP, [RAX + #32 (8-bit)] # compressed ptr ! Field FiboSample$ControlFlowException.value
134 testl RBP, RBP # compressed ptr
136 jne,s B31 P=0.000001 C=-1.000000
136
138 B27: # B4 <- B26 Freq: 4.5e-06
138 xorl R10, R10 # int
13b movl [rsp + #4], R10 # spill
140 jmp B4
140
145 B28: # B30 <- B25 Freq: 5e-07
145 movq RSI, RAX # spill
148 jmp,s B30
148
14a B29: # B30 <- B10 Freq: 2.49992e-06
14a # exception oop is in rax; no code emitted
14a movq RSI, RAX # spill
14a
14d B30: # N1 <- B18 B28 B24 B20 B29 Freq: 3.75016e-06
14d addq rsp, 32 # Destroy frame
popq rbp
152 jmp rethrow_stub
152
157 B31: # N1 <- B26 Freq: 4.5e-12
157 movl RSI, #-20 # int
nop # 3 bytes pad for loops and calls
15f call,static wrapper for: uncommon_trap(reason='null_assert' action='make_not_entrant')
# FiboSample::fibo @ bci:26 L[0]=rsp + #0 L[1]=#0 L[2]=_ L[3]=_ L[4]=_ L[5]=_ L[6]=_ L[7]=_ STK[0]=RBP
# OopMap{rbp=NarrowOop off=356}
164 int3 # ShouldNotReachHere
164
171 B32: # N1 <- B22 Freq: 4.49995e-12
171 movl RSI, #-20 # int
nop # 1 bytes pad for loops and calls
177 call,static wrapper for: uncommon_trap(reason='null_assert' action='make_not_entrant')
# FiboSample::fibo @ bci:49 L[0]=_ L[1]=rsp + #4 L[2]=#NULL L[3]=#0 L[4]=_ L[5]=_ L[6]=_ L[7]=_ STK[0]=RBP
# OopMap{rbp=NarrowOop off=380}
17c int3 # ShouldNotReachHere
17c
{method}
- klass: {other class}
- this oop: 0x000000060424c940
- method holder: 'FiboSample'
- constants: 0x000000060424c2a0 constant pool [93] for 'FiboSample' cache=0x000000060424d7b8
- access: 0x8100000a private static
- name: 'fibo'
- signature: '(I)I'
- max stack: 4
- max locals: 8
- size of params: 1
- method size: 16
- vtable index: -2
- i2i entry: 0x00002aaaab3531a0
- adapter: 0x0000000000b9fcd8
- compiled entry 0x00002aaaab40a830
- code size: 115
- code start: 0x000000060424c810
- code end (excl): 0x000000060424c883
- method data: 0x000000060424e308
- checked ex length: 1
- checked ex start: 0x000000060424c93c
- linenumber start: 0x000000060424c883
- localvar length: 12
- localvar start: 0x000000060424c8aa
#
# int ( int )
#
#r018 rsi : parm 0: int
# -- Old rsp -- Framesize: 48 --
#r191 rsp+44: in_preserve
#r190 rsp+40: return address
#r189 rsp+36: in_preserve
#r188 rsp+32: saved fp register
#r187 rsp+28: pad2, stack alignment
#r186 rsp+24: pad2, stack alignment
#r185 rsp+20: Fixed slot 1
#r184 rsp+16: Fixed slot 0
#r195 rsp+12: spill
#r194 rsp+ 8: spill
#r193 rsp+ 4: spill
#r192 rsp+ 0: spill
#
abababab N1: # B1 <- B30 B31 B14 B32 B17 Freq: 1
abababab
000 B1: # B13 B2 <- BLOCK HEAD IS JUNK Freq: 1
000 # stack bang
pushq rbp # Save rbp
subq rsp, #32 # Create frame
00c movl [rsp + #0], RSI # spill
00f cmpl RSI, #2
012 jl B13 P=0.500000 C=-1.000000
012
018 B2: # B25 B3 <- B1 Freq: 0.5
018 decl RSI # int
nop # 1 bytes pad for loops and calls
01b call,static FiboSample::fibo
# FiboSample::fibo @ bci:10 L[0]=rsp + #0 L[1]=_ L[2]=_ L[3]=_ L[4]=_ L[5]=_ L[6]=_ L[7]=_
# OopMap{off=32}
020
020 B3: # B4 <- B2 Freq: 0.49999
# Block is sole successor of call
020 movl [rsp + #4], RAX # spill
020
024 B4: # B21 B5 <- B27 B3 Freq: 0.499994
024 movl RSI, [rsp + #0] # spill
027 addl RSI, #-2 # int
nop # 1 bytes pad for loops and calls
02b call,static FiboSample::fibo
# FiboSample::fibo @ bci:30 L[0]=_ L[1]=rsp + #4 L[2]=#NULL L[3]=_ L[4]=_ L[5]=_ L[6]=_ L[7]=_
# OopMap{off=48}
030
030 B5: # B6 <- B4 Freq: 0.499984
# Block is sole successor of call
030 movl R11, [rsp + #4] # spill
035 addl R11, RAX # int
038 movl RBP, RAX # spill
038
03a B6: # B14 B7 <- B23 B5 Freq: 0.499989
03a movl R10, [rsp + #4] # spill
03f xorl R10, R11 # int
042 movl R8, RBP # spill
045 xorl R8, R11 # int
048 andl R10, R8 # int
04b testl R10, R10
04e jge,s B14 P=0.500000 C=-1.000000
04e
050 B7: # B15 B8 <- B6 Freq: 0.249994
050 # TLS is in R15
050 movq RAX, [R15 + #112 (8-bit)] # ptr
054 movq R10, RAX # spill
057 addq R10, #32 # ptr
05b cmpq R10, [R15 + #128 (32-bit)] # raw ptr
062 jnb,us B15 P=0.000100 C=-1.000000
062
064 B8: # B9 <- B7 Freq: 0.249969
064 movq [R15 + #112 (8-bit)], R10 # ptr
068 PREFETCHNTA [R10 + #192 (32-bit)] # Prefetch allocation to non-temporal cache for write
070 movl R10, narrowoop: precise klass java/lang/ArithmeticException: 0x0000000000d48c58:Constant:exact * # compressed ptr
076 movq R10, [R12 + R10 << 3 + #176] (compressed oop addressing) # ptr
07e movq [RAX], R10 # ptr
081 movl [RAX + #8 (8-bit)], narrowoop: precise klass java/lang/ArithmeticException: 0x0000000000d48c58:Constant:exact * # compressed ptr
088 movl [RAX + #12 (8-bit)], R12 # int (R12_heapbase==0)
08c movq [RAX + #16 (8-bit)], R12 # long (R12_heapbase==0)
090 movq [RAX + #24 (8-bit)], R12 # long (R12_heapbase==0)
090
094 B9: # B19 B10 <- B16 B8 Freq: 0.249994
094
094 MEMBAR-storestore (empty encoding)
094 movq RSI, RAX # spill
097 # checkcastPP of RSI
097 movq RDX, java/lang/String:exact * # ptr
0a1 movq [rsp + #8], RSI # spill
nop # 1 bytes pad for loops and calls
0a7 call,static java.lang.ArithmeticException::<init>
# java.lang.Math::addExact @ bci:20 L[0]=_ L[1]=_ L[2]=_ STK[0]=rsp + #8
# FiboSample::fibo @ bci:62 L[0]=_ L[1]=rsp + #4 L[2]=_ L[3]=RBP L[4]=_ L[5]=_ L[6]=_ L[7]=_
# OopMap{[8]=Oop off=172}
0ac
0ac B10: # B29 B11 <- B19 B9 Freq: 0.249992
0ac movl RSI, [rsp + #4] # spill
0b0 movl RDX, RBP # spill
nop # 1 bytes pad for loops and calls
0b3 call,static FiboSample::overflowedAdd
# FiboSample::fibo @ bci:77 L[0]=_ L[1]=_ L[2]=_ L[3]=_ L[4]=_ L[5]=_ L[6]=_ L[7]=_
# OopMap{off=184}
0b8
0b8 B11: # B17 B12 <- B10 Freq: 0.249987
# Block is sole successor of call
0b8 testq RAX, RAX # ptr
0bb jne,s B17 P=0.000001 C=-1.000000
0bb
0bd B12: # B14 <- B11 Freq: 0.249986
0bd xorl R11, R11 # int
0c0 jmp,s B14
0c0
0c2 B13: # B14 <- B1 Freq: 0.5
0c2 movl R11, #1 # int
0c2
0c8 B14: # N1 <- B13 B6 B12 Freq: 0.999981
0c8 movl RAX, R11 # spill
0cb addq rsp, 32 # Destroy frame
popq rbp
testl rax, [rip + #offset_to_poll_page] # Safepoint: poll for GC
0d6 ret
0d6
0d7 B15: # B18 B16 <- B7 Freq: 2.50036e-05
0d7 movq RSI, precise klass java/lang/ArithmeticException: 0x0000000000d48c58:Constant:exact * # ptr
nop # 2 bytes pad for loops and calls
0e3 call,static wrapper for: _new_instance_Java
# java.lang.Math::addExact @ bci:14 L[0]=_ L[1]=_ L[2]=_
# FiboSample::fibo @ bci:62 L[0]=_ L[1]=rsp + #4 L[2]=_ L[3]=RBP L[4]=_ L[5]=_ L[6]=_ L[7]=_
# OopMap{off=232}
0e8
0e8 B16: # B9 <- B15 Freq: 2.50031e-05
# Block is sole successor of call
0e8 jmp,s B9
0e8
0ea B17: # N1 <- B11 Freq: 2.49987e-07
0ea movl RSI, #-20 # int
0ef movq RBP, RAX # spill
nop # 1 bytes pad for loops and calls
0f3 call,static wrapper for: uncommon_trap(reason='null_assert' action='make_not_entrant')
# FiboSample::fibo @ bci:80 L[0]=_ L[1]=_ L[2]=_ L[3]=_ L[4]=_ L[5]=_ L[6]=_ L[7]=_ STK[0]=RBP
# OopMap{rbp=Oop off=248}
0f8 int3 # ShouldNotReachHere
0f8
105 B18: # B30 <- B15 Freq: 2.50036e-10
105 # exception oop is in rax; no code emitted
105 movq RSI, RAX # spill
108 jmp,s B30
108
10a B19: # B10 B20 <- B9 Freq: 2.49994e-06
10a # exception oop is in rax; no code emitted
10a movl R11, [RAX + #8 (8-bit)] # compressed klass ptr
10e cmpl R11, narrowoop: precise klass java/lang/ArithmeticException: 0x0000000000d48c58:Constant:exact * # compressed ptr
115 je,us B10 P=0.900000 C=-1.000000
115
117 B20: # B30 <- B19 Freq: 2.49995e-07
117 movq RSI, RAX # spill
11a jmp,s B30
11a
11c B21: # B24 B22 <- B4 Freq: 4.99994e-06
11c # exception oop is in rax; no code emitted
11c movl R11, [RAX + #8 (8-bit)] # compressed klass ptr
120 cmpl R11, narrowoop: precise klass FiboSample$ControlFlowException: 0x0000000000d46478:Constant:exact * # compressed ptr
127 jne,us B24 P=0.100000 C=-1.000000
127
129 B22: # B32 B23 <- B21 Freq: 4.49995e-06
129 # checkcastPP of RAX
129 movl RBP, [RAX + #32 (8-bit)] # compressed ptr ! Field FiboSample$ControlFlowException.value
12c testl RBP, RBP # compressed ptr
12e jne,s B32 P=0.000001 C=-1.000000
12e
130 B23: # B6 <- B22 Freq: 4.49995e-06
130 movl R11, [rsp + #4] # spill
135 xorl RBP, RBP # int
137 jmp B6
137
13c B24: # B30 <- B21 Freq: 4.99995e-07
13c movq RSI, RAX # spill
13f jmp,s B30
13f
141 B25: # B28 B26 <- B2 Freq: 5e-06
141 # exception oop is in rax; no code emitted
141 movl R10, [RAX + #8 (8-bit)] # compressed klass ptr
145 cmpl R10, narrowoop: precise klass FiboSample$ControlFlowException: 0x0000000000d46478:Constant:exact * # compressed ptr
14c jne,us B28 P=0.100000 C=-1.000000
14c
14e B26: # B31 B27 <- B25 Freq: 4.5e-06
14e # checkcastPP of RAX
14e movl RBP, [RAX + #32 (8-bit)] # compressed ptr ! Field FiboSample$ControlFlowException.value
151 testl RBP, RBP # compressed ptr
153 jne,s B31 P=0.000001 C=-1.000000
153
155 B27: # B4 <- B26 Freq: 4.5e-06
155 xorl R10, R10 # int
158 movl [rsp + #4], R10 # spill
15d jmp B4
15d
162 B28: # B30 <- B25 Freq: 5e-07
162 movq RSI, RAX # spill
165 jmp,s B30
165
167 B29: # B30 <- B10 Freq: 2.49992e-06
167 # exception oop is in rax; no code emitted
167 movq RSI, RAX # spill
167
16a B30: # N1 <- B18 B28 B24 B20 B29 Freq: 3.75016e-06
16a addq rsp, 32 # Destroy frame
popq rbp
16f jmp rethrow_stub
16f
174 B31: # N1 <- B26 Freq: 4.5e-12
174 movl RSI, #-20 # int
nop # 2 bytes pad for loops and calls
17b call,static wrapper for: uncommon_trap(reason='null_assert' action='make_not_entrant')
# FiboSample::fibo @ bci:26 L[0]=rsp + #0 L[1]=#0 L[2]=_ L[3]=_ L[4]=_ L[5]=_ L[6]=_ L[7]=_ STK[0]=RBP
# OopMap{rbp=NarrowOop off=384}
180 int3 # ShouldNotReachHere
180
18d B32: # N1 <- B22 Freq: 4.49995e-12
18d movl RSI, #-20 # int
nop # 1 bytes pad for loops and calls
193 call,static wrapper for: uncommon_trap(reason='null_assert' action='make_not_entrant')
# FiboSample::fibo @ bci:49 L[0]=_ L[1]=rsp + #4 L[2]=#NULL L[3]=#0 L[4]=_ L[5]=_ L[6]=_ L[7]=_ STK[0]=RBP
# OopMap{rbp=NarrowOop off=408}
198 int3 # ShouldNotReachHere
198
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.