Merge pull request #2454 from tastywheattasteslikechicken/FixVtableAbort
[mono.git] / mono / mini / test_op_il_seq_point.sh
1 #!/bin/bash
2
3 TEST_FILE=$1
4 USE_AOT=$2
5
6 TMP_FILE_PREFIX=$(basename $0).tmp
7 BASEDIR=$(dirname $0)
8
9 MONO_PATH=$BASEDIR/../../mcs/class/lib/net_4_x:$BASEDIR
10 RUNTIME=$BASEDIR/../../runtime/mono-wrapper
11
12 trap "rm -rf ${TMP_FILE_PREFIX}*" EXIT
13
14 tmp_file () {
15         mktemp ./${TMP_FILE_PREFIX}XXXX
16 }
17
18 clean_aot () {
19         rm -rf *.exe.so *.exe.dylib *.exe.dylib.dSYM
20 }
21
22 # The test compares the generated native code size between a compilation with and without seq points.
23 # In some architectures ie:amd64 when possible 32bit instructions and registers are used instead of 64bit ones.
24 # Using MONO_DEBUG=single-imm-size avoids 32bit optimizations thus mantaining the native code size between compilations.
25
26 get_methods () {
27         if [ -z $4 ]; then
28                 MONO_PATH=$1 $2 -v --compile-all=1 $3 | grep '^Method .*code length' | sed 's/emitted[^()]*//' | sort
29         else
30                 clean_aot
31                 MONO_PATH=$1 $2 -v --aot $3 | grep '^Method .*code length' | sed 's/emitted[^()]*//' | sort
32         fi
33 }
34
35 get_method () {
36         if [ -z $5 ]; then
37                 MONO_VERBOSE_METHOD="$4" MONO_PATH=$1 $2 --compile-all=1 $3 | sed 's/0x[0-9a-fA-F]*/0x0/g'
38         else
39                 clean_aot
40                 MONO_VERBOSE_METHOD="$4" MONO_PATH=$1 $2 --aot $3 | sed 's/0x[0-9a-fA-F]*/0x0/g'
41         fi
42 }
43
44 diff_methods () {
45         TMP_FILE=$(tmp_file)
46         echo "$(MONO_DEBUG=single-imm-size get_methods $1 $2 $3 $4)" >$TMP_FILE
47         diff <(cat $TMP_FILE) <(echo "$(MONO_DEBUG=gen-compact-seq-points,single-imm-size get_methods $1 $2 $3 $4)")
48 }
49
50 diff_method () {
51         TMP_FILE=$(tmp_file)
52         echo "$(MONO_DEBUG=single-imm-size get_method $1 $2 $3 $4 $5)" >$TMP_FILE
53         sdiff -w 150 <(cat $TMP_FILE) <(echo "$(MONO_DEBUG=gen-compact-seq-points,single-imm-size get_method $1 $2 $3 $4 $5 | grep -Ev il_seq_point)")
54 }
55
56 get_method_name () {
57         echo $1 | sed -E 's/.*Method (\([^)]*\) )?([^ ]*).*/\2/g'
58 }
59
60 get_method_length () {
61         echo $1 | sed 's/.*code length \([0-9]*\).*/\1/'
62 }
63
64 if [ -z $USE_AOT ]; then
65         echo "Checking unintended native code changes in $TEST_FILE without AOT"
66 else
67         echo "Checking unintended native code changes in $TEST_FILE with AOT"
68 fi
69
70 TMP_FILE=$(tmp_file)
71
72 echo "$(diff_methods $MONO_PATH $RUNTIME $TEST_FILE $USE_AOT)" > $TMP_FILE
73
74 CHANGES=0
75 METHOD=""
76 MIN_SIZE=10000
77
78 while read line; do
79         if [ "$line" != "" ]; then
80                 echo $line
81                 if [[ ${line:0:1} == "<" ]]; then
82                         CHANGES=$((CHANGES+1))
83                         SIZE=$(get_method_length "$line")
84                         if [[ SIZE -lt MIN_SIZE ]]; then
85                                 MIN_SIZE=$SIZE
86                                 METHOD="$line"
87                         fi
88                 fi
89         fi
90 done < $TMP_FILE
91
92 TESTRESULT_FILE=TestResult-op_il_seq_point.tmp
93
94 echo -n "              <test-case name=\"MonoTests.op_il_seq_point.${TEST_FILE}${USE_AOT}\" executed=\"True\" time=\"0\" asserts=\"0\" success=\"" >> $TESTRESULT_FILE
95
96 if [ $CHANGES != 0 ]
97 then
98         METHOD_NAME=$(get_method_name "$METHOD")
99
100         echo "False\">" >> $TESTRESULT_FILE
101         echo "                <failure>" >> $TESTRESULT_FILE
102         echo -n "                  <message><![CDATA[" >> $TESTRESULT_FILE
103         echo "Detected OP_IL_SEQ_POINT incompatibility on $TEST_FILE" >> $TESTRESULT_FILE
104         echo "  $CHANGES methods differ when sequence points are enabled." >> $TESTRESULT_FILE
105         echo '  This is probably caused by a runtime optimization that is not handling OP_IL_SEQ_POINT' >> $TESTRESULT_FILE
106         echo '' >> $TESTRESULT_FILE
107         echo "Diff $METHOD_NAME" >> $TESTRESULT_FILE
108         echo "Without IL_OP_SEQ_POINT                                                         With IL_OP_SEQ_POINT" >> $TESTRESULT_FILE
109         echo -n "$(diff_method $MONO_PATH $RUNTIME $TEST_FILE $METHOD_NAME $USE_AOT)" >> $TESTRESULT_FILE
110         echo "]]></message>" >> $TESTRESULT_FILE
111         echo "                  <stack-trace>" >> $TESTRESULT_FILE
112         echo "                  </stack-trace>" >> $TESTRESULT_FILE
113         echo "                </failure>" >> $TESTRESULT_FILE
114         echo "              </test-case>" >> $TESTRESULT_FILE
115
116         echo ''
117         echo "Detected OP_IL_SEQ_POINT incompatibility on $TEST_FILE"
118         echo "  $CHANGES methods differ when sequence points are enabled."
119         echo '  This is probably caused by a runtime optimization that is not handling OP_IL_SEQ_POINT'
120
121         echo ''
122         echo "Diff $METHOD_NAME"
123         echo "Without IL_OP_SEQ_POINT                                                         With IL_OP_SEQ_POINT"
124         echo "$(diff_method $MONO_PATH $RUNTIME $TEST_FILE $METHOD_NAME $USE_AOT)"
125         exit 1
126 else
127         echo "True\" />" >> $TESTRESULT_FILE
128 fi