Created
August 9, 2011 09:44
-
-
Save rednaxelafx/1133678 to your computer and use it in GitHub Desktop.
failed attempt to add Phi::exact_type() to HotSpot C1
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff -r 4aa5974a06dd src/share/vm/c1/c1_Instruction.cpp | |
--- a/src/share/vm/c1/c1_Instruction.cpp Sat Aug 06 08:28:08 2011 -0700 | |
+++ b/src/share/vm/c1/c1_Instruction.cpp Mon Aug 08 23:54:46 2011 +0800 | |
@@ -29,6 +29,7 @@ | |
#include "c1/c1_ValueStack.hpp" | |
#include "ci/ciObjArrayKlass.hpp" | |
#include "ci/ciTypeArrayKlass.hpp" | |
+#include "utilities/stack.inline.hpp" | |
// Implementation of Instruction | |
@@ -135,6 +136,59 @@ | |
} | |
+static | |
+ciType* find_exact_type(const Phi* self, Stack<const Phi*>& visited) { | |
+ // check cycles | |
+ StackIterator<const Phi*> iter(visited); | |
+ while (!iter.is_empty()) { | |
+ // cycle found, break it | |
+ if (self == iter.next()) return NULL; | |
+ } | |
+ | |
+ visited.push(self); | |
+ | |
+ ciType* the_type = NULL; | |
+ | |
+ for (int i = 0; i < self->operand_count(); i++) { | |
+ Value opd = self->operand_at(i); | |
+ if (self == opd || opd->as_UnsafeGetRaw() != NULL) continue; // skip over itself and UnsafeGetRaw | |
+ | |
+ ciType* opd_exact_type; | |
+ const Phi* opd_phi = opd->as_Phi(); | |
+ if (opd_phi != NULL) { | |
+ opd_exact_type = find_exact_type(opd_phi, visited); | |
+ } else { | |
+ opd_exact_type = opd->exact_type(); | |
+ } | |
+ | |
+ // if any of the operands that we care doesn't have exact type, give up | |
+ if (opd_exact_type == NULL) return NULL; | |
+ | |
+ if (the_type != NULL) { | |
+ // be conservative here: iff all operands have the same exact type, return that type, | |
+ // otherwise give up and return null | |
+ if (!the_type->equals(opd_exact_type)) { | |
+ the_type = NULL; | |
+ break; | |
+ } | |
+ } else { | |
+ the_type = opd_exact_type; | |
+ } | |
+ } | |
+ | |
+ visited.pop(); | |
+ | |
+ return the_type; | |
+} | |
+ | |
+ciType* Phi::exact_type() const { | |
+ assert(!is_illegal(), "must be a legal Phi"); | |
+ | |
+ Stack<const Phi*> visited; | |
+ return find_exact_type(this, visited); | |
+} | |
+ | |
+ | |
ciType* Local::exact_type() const { | |
ciType* type = declared_type(); | |
diff -r 4aa5974a06dd src/share/vm/c1/c1_Instruction.hpp | |
--- a/src/share/vm/c1/c1_Instruction.hpp Sat Aug 06 08:28:08 2011 -0700 | |
+++ b/src/share/vm/c1/c1_Instruction.hpp Mon Aug 08 23:54:46 2011 +0800 | |
@@ -501,6 +501,7 @@ | |
virtual RoundFP* as_RoundFP() { return NULL; } | |
virtual ExceptionObject* as_ExceptionObject() { return NULL; } | |
virtual UnsafeOp* as_UnsafeOp() { return NULL; } | |
+ virtual UnsafeGetRaw* as_UnsafeGetRaw() { return NULL; } | |
virtual void visit(InstructionVisitor* v) = 0; | |
@@ -585,6 +586,8 @@ | |
cannot_simplify = 1 << 1 | |
}; | |
+ ciType* exact_type() const; | |
+ | |
// accessors | |
bool is_local() const { return _index >= 0; } | |
bool is_on_stack() const { return !is_local(); } |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
CompilerOracle: compileonly WrongInline.test | |
VM option '+PrintCompilation' | |
VM option '+PrintInlining' | |
VM option '+PrintIRDuringConstruction' | |
VM option '+PrintPhiFunctions' | |
VM option 'CompileThreshold=2' | |
CompilerOracle: compileonly java/util*.* | |
690 89 WrongInline::test (64 bytes) | |
********** try_merge for block B0 | |
no existing state for block B0 | |
----------------------------------- | |
new state for block B0 | |
static void WrongInline.test(jobject)empty stack | |
local 0 a7 local[index 0] | |
local 1 null | |
local 2 null | |
local 3 null | |
=================================== | |
first call of try_merge for this block | |
********** try_merge for block B0 successful | |
B0 (SV) [0, -1] sux: B1 B2 | |
empty stack | |
inlining depth 0 | |
__bci__use__tid____instr____________________________________ | |
locals size: 4 stack size: 0 | |
. 1 0 i8 a7.length | |
2 0 i9 2 | |
. 3 0 i10 i8 % i9 | |
4 0 i11 0 | |
. 4 0 12 if i10 != i11 then B2 else B1 | |
********** try_merge for block B1 | |
no existing state for block B1 | |
----------------------------------- | |
new state for block B1 | |
static void WrongInline.test(jobject)empty stack | |
local 0 a7 local[index 0] | |
local 1 null | |
local 2 null | |
local 3 null | |
=================================== | |
first call of try_merge for this block | |
invalidating dead local 0 | |
********** try_merge for block B1 successful | |
********** try_merge for block B2 | |
no existing state for block B2 | |
----------------------------------- | |
new state for block B2 | |
static void WrongInline.test(jobject)empty stack | |
local 0 a7 local[index 0] | |
local 1 null | |
local 2 null | |
local 3 null | |
=================================== | |
first call of try_merge for this block | |
invalidating dead local 0 | |
********** try_merge for block B2 successful | |
B1 (V) [7, -1] sux: B3 pred: B0 | |
empty stack | |
inlining depth 0 | |
__bci__use__tid____instr____________________________________ | |
locals size: 4 stack size: 0 | |
. 7 0 a13 new instance java/util/ArrayList | |
@ 11 java.util.ArrayList::<init> (7 bytes) | |
B1 (V) [7, -1] sux: B3 pred: B0 | |
empty stack | |
inlining depth 0 | |
__bci__use__tid____instr____________________________________ | |
locals size: 1 stack size: 0 | |
1 0 i16 10 | |
@ 3 java.util.ArrayList::<init> (44 bytes) callee is too large | |
. 3 0 v17 a13.invokespecial(i16) | |
java/util/ArrayList.<init>(I)V | |
. 14 0 18 goto B7 | |
********** try_merge for block B7 | |
no existing state for block B7 | |
----------------------------------- | |
new state for block B7 | |
static void WrongInline.test(jobject) 1 a13 new instance java/util/ArrayList | |
local 0 null | |
local 1 null | |
local 2 null | |
local 3 null | |
=================================== | |
first call of try_merge for this block | |
********** try_merge for block B7 successful | |
. 15 0 19 goto B3 | |
********** try_merge for block B3 | |
no existing state for block B3 | |
----------------------------------- | |
new state for block B3 | |
static void WrongInline.test(jobject)empty stack | |
local 0 null | |
local 1 a13 new instance java/util/ArrayList | |
local 2 null | |
local 3 null | |
=================================== | |
first call of try_merge for this block | |
********** try_merge for block B3 successful | |
B2 (V) [18, -1] sux: B3 pred: B0 | |
empty stack | |
inlining depth 0 | |
__bci__use__tid____instr____________________________________ | |
locals size: 4 stack size: 0 | |
. 18 0 a20 new instance java/util/ArrayList | |
22 0 i21 20 | |
@ 24 java.util.ArrayList::<init> (44 bytes) callee is too large | |
. 24 0 v22 a20.invokespecial(i21) | |
java/util/ArrayList.<init>(I)V | |
. 28 0 23 goto B3 | |
********** try_merge for block B3 | |
existing state for block B3 | |
static void WrongInline.test(jobject)empty stack | |
local 0 null | |
local 1 a13 new instance java/util/ArrayList | |
local 2 null | |
local 3 null | |
----------------------------------- | |
new state for block B3 | |
static void WrongInline.test(jobject)empty stack | |
local 0 null | |
local 1 a20 new instance java/util/ArrayList | |
local 2 null | |
local 3 null | |
=================================== | |
exisiting state found | |
creating phi functions on demand | |
creating phi-function a24 for local 1 | |
********** try_merge for block B3 successful | |
B3 (V) [28, -1] sux: B4 pred: B1 B2 | |
empty stack | |
inlining depth 0 | |
__bci__use__tid____instr____________________________________ | |
locals size: 4 stack size: 0 | |
28 0 i25 0 | |
. 30 0 26 goto B4 | |
********** try_merge for block B4 | |
no existing state for block B4 | |
----------------------------------- | |
new state for block B4 | |
static void WrongInline.test(jobject)empty stack | |
local 0 null | |
local 1 a24 phi function, a13, a20 | |
local 2 i25 0 | |
local 3 null | |
=================================== | |
first call of try_merge for this block | |
loop header block, initializing phi functions | |
creating phi-function a27 for local 1 | |
creating phi-function i28 for local 2 | |
********** try_merge for block B4 successful | |
B4 (LHV) [30, -1] sux: B5 B6 pred: B3 | |
empty stack | |
inlining depth 0 | |
__bci__use__tid____instr____________________________________ | |
locals size: 4 stack size: 0 | |
31 0 i29 2 | |
. 32 0 30 if i28 >= i29 then B6 else B5 | |
********** try_merge for block B5 | |
no existing state for block B5 | |
----------------------------------- | |
new state for block B5 | |
static void WrongInline.test(jobject)empty stack | |
local 0 null | |
local 1 a27 phi function, a24 | |
local 2 i28 phi function, i25 | |
local 3 null | |
=================================== | |
first call of try_merge for this block | |
********** try_merge for block B5 successful | |
********** try_merge for block B6 | |
no existing state for block B6 | |
----------------------------------- | |
new state for block B6 | |
static void WrongInline.test(jobject)empty stack | |
local 0 null | |
local 1 a27 phi function, a24 | |
local 2 i28 phi function, i25 | |
local 3 null | |
=================================== | |
first call of try_merge for this block | |
invalidating dead local 1 | |
invalidating dead local 2 | |
********** try_merge for block B6 successful | |
B5 (V) [35, -1] sux: B4 pred: B4 | |
empty stack | |
inlining depth 0 | |
__bci__use__tid____instr____________________________________ | |
locals size: 4 stack size: 0 | |
@ 36 java.util.ArrayList::size (5 bytes) | |
. 36 0 a31 null_check(a27) | |
B5 (V) [35, -1] sux: B4 pred: B4 | |
empty stack | |
inlining depth 0 | |
__bci__use__tid____instr____________________________________ | |
locals size: 1 stack size: 0 | |
. 1 0 i34 a27._12 (I) | |
. 41 0 35 goto B9 | |
********** try_merge for block B9 | |
no existing state for block B9 | |
----------------------------------- | |
new state for block B9 | |
static void WrongInline.test(jobject) 1 i34 a27._12 (I) | |
local 0 null | |
local 1 a27 phi function, a24 | |
local 2 i28 phi function, i25 | |
local 3 null | |
=================================== | |
first call of try_merge for this block | |
invalidating dead local 1 | |
********** try_merge for block B9 successful | |
42 0 a36 <instance 0x09d5e360> | |
. 42 0 a37 a36._108 (L) | |
!m @ 46 java.io.PrintStream::println (24 bytes) excluded by CompilerOracle | |
. 46 0 a38 null_check(a37) | |
. 46 0 v39 a37.invokespecial(i34) | |
java/io/PrintStream.println(I)V | |
. 49 0 a40 new instance java/util/LinkedList | |
@ 53 java.util.LinkedList::<init> (10 bytes) | |
B5 (V) [35, 41] -> B9 sux: B9 pred: B4 | |
empty stack | |
inlining depth 0 | |
__bci__use__tid____instr____________________________________ | |
locals size: 1 stack size: 0 | |
@ 1 java.util.AbstractSequentialList::<init> (5 bytes) | |
B5 (V) [35, 41] -> B9 sux: B9 pred: B4 | |
empty stack | |
inlining depth 0 | |
__bci__use__tid____instr____________________________________ | |
locals size: 1 stack size: 0 | |
@ 1 java.util.AbstractList::<init> (10 bytes) | |
B5 (V) [35, 41] -> B9 sux: B9 pred: B4 | |
empty stack | |
inlining depth 0 | |
__bci__use__tid____instr____________________________________ | |
locals size: 1 stack size: 0 | |
@ 1 java.util.AbstractCollection::<init> (5 bytes) | |
B5 (V) [35, 41] -> B9 sux: B9 pred: B4 | |
empty stack | |
inlining depth 0 | |
__bci__use__tid____instr____________________________________ | |
locals size: 1 stack size: 0 | |
@ 1 java.lang.Object::<init> (1 bytes) excluded by CompilerOracle | |
. 1 0 v49 a40.invokespecial() | |
java/lang/Object.<init>()V | |
. 4 0 50 goto B17 | |
********** try_merge for block B17 | |
no existing state for block B17 | |
----------------------------------- | |
new state for block B17 | |
virtual void java.util.AbstractList.<init>()empty stack | |
local 0 a40 new instance java/util/LinkedList | |
virtual void java.util.AbstractSequentialList.<init>()empty stack | |
local 0 a40 new instance java/util/LinkedList | |
virtual void java.util.LinkedList.<init>()empty stack | |
local 0 a40 new instance java/util/LinkedList | |
static void WrongInline.test(jobject) 1 a40 new instance java/util/LinkedList | |
local 0 null | |
local 1 a27 phi function, a24 | |
local 2 i28 phi function, i25 | |
local 3 i34 a27._12 (I) | |
=================================== | |
first call of try_merge for this block | |
********** try_merge for block B17 successful | |
5 0 i51 0 | |
. 6 0 i52 a40._8 := i51 (I) | |
. 4 0 53 goto B15 | |
********** try_merge for block B15 | |
no existing state for block B15 | |
----------------------------------- | |
new state for block B15 | |
virtual void java.util.AbstractSequentialList.<init>()empty stack | |
local 0 a40 new instance java/util/LinkedList | |
virtual void java.util.LinkedList.<init>()empty stack | |
local 0 a40 new instance java/util/LinkedList | |
static void WrongInline.test(jobject) 1 a40 new instance java/util/LinkedList | |
local 0 null | |
local 1 a27 phi function, a24 | |
local 2 i28 phi function, i25 | |
local 3 i34 a27._12 (I) | |
=================================== | |
first call of try_merge for this block | |
invalidating dead local 0 | |
********** try_merge for block B15 successful | |
. 4 0 54 goto B13 | |
********** try_merge for block B13 | |
no existing state for block B13 | |
----------------------------------- | |
new state for block B13 | |
virtual void java.util.LinkedList.<init>()empty stack | |
local 0 a40 new instance java/util/LinkedList | |
static void WrongInline.test(jobject) 1 a40 new instance java/util/LinkedList | |
local 0 null | |
local 1 a27 phi function, a24 | |
local 2 i28 phi function, i25 | |
local 3 i34 a27._12 (I) | |
=================================== | |
first call of try_merge for this block | |
********** try_merge for block B13 successful | |
. 6 0 i56 a40._12 := i51 (I) | |
. 56 0 57 goto B11 | |
********** try_merge for block B11 | |
no existing state for block B11 | |
----------------------------------- | |
new state for block B11 | |
static void WrongInline.test(jobject) 1 a40 new instance java/util/LinkedList | |
local 0 null | |
local 1 a27 phi function, a24 | |
local 2 i28 phi function, i25 | |
local 3 i34 a27._12 (I) | |
=================================== | |
first call of try_merge for this block | |
invalidating dead local 1 | |
invalidating dead local 3 | |
********** try_merge for block B11 successful | |
57 0 i58 1 | |
57 0 i59 i28 + i58 | |
. 60 0 60 goto B4 (safepoint) | |
********** try_merge for block B4 | |
existing state for block B4 | |
static void WrongInline.test(jobject)empty stack | |
local 0 null | |
local 1 a27 phi function, a24, a40 | |
local 2 i28 phi function, i25, i59 | |
local 3 null | |
----------------------------------- | |
new state for block B4 | |
static void WrongInline.test(jobject)empty stack | |
local 0 null | |
local 1 a40 new instance java/util/LinkedList | |
local 2 i59 i28 + i58 | |
local 3 i34 a27._12 (I) | |
=================================== | |
exisiting state found | |
loop header block, phis must be present | |
********** try_merge for block B4 successful | |
B6 (V) [63, -1] pred: B4 | |
empty stack | |
inlining depth 0 | |
__bci__use__tid____instr____________________________________ | |
locals size: 4 stack size: 0 | |
. 63 0 v61 return | |
702 90 java.util.LinkedList::size (5 bytes) | |
********** try_merge for block B0 | |
no existing state for block B0 | |
----------------------------------- | |
new state for block B0 | |
virtual jint java.util.LinkedList.size()empty stack | |
local 0 a1 local[index 0] | |
=================================== | |
first call of try_merge for this block | |
********** try_merge for block B0 successful | |
B0 (SV) [0, -1] | |
empty stack | |
inlining depth 0 | |
__bci__use__tid____instr____________________________________ | |
locals size: 1 stack size: 0 | |
. 1 0 i2 a1._12 (I) | |
. 4 0 i3 ireturn i2 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import java.util.*; | |
/* | |
*/ | |
public class WrongInline { | |
public static void test(String[] args) { | |
List<?> list; | |
if (args.length % 2 == 0) { | |
list = new ArrayList<String>(); // list1 | |
} else { | |
list = new ArrayList<String>(32); // list2 | |
} | |
// list3 = Phi(list1, list2) | |
for (int i = 0; i < 2; i++) { | |
// list4 = Phi(list3, list5) | |
int size = list.size(); // will incorrectly inline ArrayList::size() here | |
System.out.println(size); | |
list = new LinkedList<String>(); // list5 | |
} | |
} | |
public static void main(String[] args) throws Exception { | |
test(args); | |
test(args); | |
test(args); | |
System.in.read(); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment