reg_type_test.cc revision 7da9586b559290e1c16207c6513ffe485de61655
1/*
2 * Copyright (C) 2012 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include "reg_type.h"
18
19#include <set>
20
21#include "base/casts.h"
22#include "common_runtime_test.h"
23#include "reg_type_cache-inl.h"
24#include "scoped_thread_state_change.h"
25#include "thread-inl.h"
26
27namespace art {
28namespace verifier {
29
30class RegTypeTest : public CommonRuntimeTest {};
31
32TEST_F(RegTypeTest, ConstLoHi) {
33  // Tests creating primitive types types.
34  ScopedObjectAccess soa(Thread::Current());
35  RegTypeCache cache(true);
36  RegType& ref_type_const_0 = cache.FromCat1Const(10, true);
37  RegType& ref_type_const_1 = cache.FromCat1Const(10, true);
38  RegType& ref_type_const_2 = cache.FromCat1Const(30, true);
39  RegType& ref_type_const_3 = cache.FromCat1Const(30, false);
40  EXPECT_TRUE(ref_type_const_0.Equals(ref_type_const_1));
41  EXPECT_FALSE(ref_type_const_0.Equals(ref_type_const_2));
42  EXPECT_FALSE(ref_type_const_0.Equals(ref_type_const_3));
43
44  RegType& ref_type_const_wide_0 = cache.FromCat2ConstHi(50, true);
45  RegType& ref_type_const_wide_1 = cache.FromCat2ConstHi(50, true);
46  EXPECT_TRUE(ref_type_const_wide_0.Equals(ref_type_const_wide_1));
47
48  RegType& ref_type_const_wide_2 = cache.FromCat2ConstLo(50, true);
49  RegType& ref_type_const_wide_3 = cache.FromCat2ConstLo(50, true);
50  RegType& ref_type_const_wide_4 = cache.FromCat2ConstLo(55, true);
51  EXPECT_TRUE(ref_type_const_wide_2.Equals(ref_type_const_wide_3));
52  EXPECT_FALSE(ref_type_const_wide_2.Equals(ref_type_const_wide_4));
53}
54
55TEST_F(RegTypeTest, Pairs) {
56  ScopedObjectAccess soa(Thread::Current());
57  RegTypeCache cache(true);
58  int64_t val = static_cast<int32_t>(1234);
59  RegType& precise_lo = cache.FromCat2ConstLo(static_cast<int32_t>(val), true);
60  RegType& precise_hi = cache.FromCat2ConstHi(static_cast<int32_t>(val >> 32), true);
61  RegType& precise_const = cache.FromCat1Const(static_cast<int32_t>(val >> 32), true);
62  RegType& long_lo = cache.LongLo();
63  RegType& long_hi = cache.LongHi();
64  // Check sanity of types.
65  EXPECT_TRUE(precise_lo.IsLowHalf());
66  EXPECT_FALSE(precise_hi.IsLowHalf());
67  EXPECT_FALSE(precise_lo.IsHighHalf());
68  EXPECT_TRUE(precise_hi.IsHighHalf());
69  EXPECT_TRUE(long_hi.IsLongHighTypes());
70  EXPECT_TRUE(precise_hi.IsLongHighTypes());
71  // Check Pairing.
72  EXPECT_FALSE(precise_lo.CheckWidePair(precise_const));
73  EXPECT_TRUE(precise_lo.CheckWidePair(precise_hi));
74  // Test Merging.
75  EXPECT_TRUE((long_lo.Merge(precise_lo, &cache)).IsLongTypes());
76  EXPECT_TRUE((long_hi.Merge(precise_hi, &cache)).IsLongHighTypes());
77}
78
79TEST_F(RegTypeTest, Primitives) {
80  ScopedObjectAccess soa(Thread::Current());
81  RegTypeCache cache(true);
82
83  RegType& bool_reg_type = cache.Boolean();
84  EXPECT_FALSE(bool_reg_type.IsUndefined());
85  EXPECT_FALSE(bool_reg_type.IsConflict());
86  EXPECT_FALSE(bool_reg_type.IsZero());
87  EXPECT_FALSE(bool_reg_type.IsOne());
88  EXPECT_FALSE(bool_reg_type.IsLongConstant());
89  EXPECT_TRUE(bool_reg_type.IsBoolean());
90  EXPECT_FALSE(bool_reg_type.IsByte());
91  EXPECT_FALSE(bool_reg_type.IsChar());
92  EXPECT_FALSE(bool_reg_type.IsShort());
93  EXPECT_FALSE(bool_reg_type.IsInteger());
94  EXPECT_FALSE(bool_reg_type.IsLong());
95  EXPECT_FALSE(bool_reg_type.IsFloat());
96  EXPECT_FALSE(bool_reg_type.IsDouble());
97  EXPECT_FALSE(bool_reg_type.IsReference());
98  EXPECT_FALSE(bool_reg_type.IsLowHalf());
99  EXPECT_FALSE(bool_reg_type.IsHighHalf());
100  EXPECT_FALSE(bool_reg_type.IsLongOrDoubleTypes());
101  EXPECT_FALSE(bool_reg_type.IsReferenceTypes());
102  EXPECT_TRUE(bool_reg_type.IsCategory1Types());
103  EXPECT_FALSE(bool_reg_type.IsCategory2Types());
104  EXPECT_TRUE(bool_reg_type.IsBooleanTypes());
105  EXPECT_TRUE(bool_reg_type.IsByteTypes());
106  EXPECT_TRUE(bool_reg_type.IsShortTypes());
107  EXPECT_TRUE(bool_reg_type.IsCharTypes());
108  EXPECT_TRUE(bool_reg_type.IsIntegralTypes());
109  EXPECT_FALSE(bool_reg_type.IsFloatTypes());
110  EXPECT_FALSE(bool_reg_type.IsLongTypes());
111  EXPECT_FALSE(bool_reg_type.IsDoubleTypes());
112  EXPECT_TRUE(bool_reg_type.IsArrayIndexTypes());
113  EXPECT_FALSE(bool_reg_type.IsNonZeroReferenceTypes());
114
115  RegType& byte_reg_type = cache.Byte();
116  EXPECT_FALSE(byte_reg_type.IsUndefined());
117  EXPECT_FALSE(byte_reg_type.IsConflict());
118  EXPECT_FALSE(byte_reg_type.IsZero());
119  EXPECT_FALSE(byte_reg_type.IsOne());
120  EXPECT_FALSE(byte_reg_type.IsLongConstant());
121  EXPECT_FALSE(byte_reg_type.IsBoolean());
122  EXPECT_TRUE(byte_reg_type.IsByte());
123  EXPECT_FALSE(byte_reg_type.IsChar());
124  EXPECT_FALSE(byte_reg_type.IsShort());
125  EXPECT_FALSE(byte_reg_type.IsInteger());
126  EXPECT_FALSE(byte_reg_type.IsLong());
127  EXPECT_FALSE(byte_reg_type.IsFloat());
128  EXPECT_FALSE(byte_reg_type.IsDouble());
129  EXPECT_FALSE(byte_reg_type.IsReference());
130  EXPECT_FALSE(byte_reg_type.IsLowHalf());
131  EXPECT_FALSE(byte_reg_type.IsHighHalf());
132  EXPECT_FALSE(byte_reg_type.IsLongOrDoubleTypes());
133  EXPECT_FALSE(byte_reg_type.IsReferenceTypes());
134  EXPECT_TRUE(byte_reg_type.IsCategory1Types());
135  EXPECT_FALSE(byte_reg_type.IsCategory2Types());
136  EXPECT_FALSE(byte_reg_type.IsBooleanTypes());
137  EXPECT_TRUE(byte_reg_type.IsByteTypes());
138  EXPECT_TRUE(byte_reg_type.IsShortTypes());
139  EXPECT_FALSE(byte_reg_type.IsCharTypes());
140  EXPECT_TRUE(byte_reg_type.IsIntegralTypes());
141  EXPECT_FALSE(byte_reg_type.IsFloatTypes());
142  EXPECT_FALSE(byte_reg_type.IsLongTypes());
143  EXPECT_FALSE(byte_reg_type.IsDoubleTypes());
144  EXPECT_TRUE(byte_reg_type.IsArrayIndexTypes());
145  EXPECT_FALSE(byte_reg_type.IsNonZeroReferenceTypes());
146
147  RegType& char_reg_type = cache.Char();
148  EXPECT_FALSE(char_reg_type.IsUndefined());
149  EXPECT_FALSE(char_reg_type.IsConflict());
150  EXPECT_FALSE(char_reg_type.IsZero());
151  EXPECT_FALSE(char_reg_type.IsOne());
152  EXPECT_FALSE(char_reg_type.IsLongConstant());
153  EXPECT_FALSE(char_reg_type.IsBoolean());
154  EXPECT_FALSE(char_reg_type.IsByte());
155  EXPECT_TRUE(char_reg_type.IsChar());
156  EXPECT_FALSE(char_reg_type.IsShort());
157  EXPECT_FALSE(char_reg_type.IsInteger());
158  EXPECT_FALSE(char_reg_type.IsLong());
159  EXPECT_FALSE(char_reg_type.IsFloat());
160  EXPECT_FALSE(char_reg_type.IsDouble());
161  EXPECT_FALSE(char_reg_type.IsReference());
162  EXPECT_FALSE(char_reg_type.IsLowHalf());
163  EXPECT_FALSE(char_reg_type.IsHighHalf());
164  EXPECT_FALSE(char_reg_type.IsLongOrDoubleTypes());
165  EXPECT_FALSE(char_reg_type.IsReferenceTypes());
166  EXPECT_TRUE(char_reg_type.IsCategory1Types());
167  EXPECT_FALSE(char_reg_type.IsCategory2Types());
168  EXPECT_FALSE(char_reg_type.IsBooleanTypes());
169  EXPECT_FALSE(char_reg_type.IsByteTypes());
170  EXPECT_FALSE(char_reg_type.IsShortTypes());
171  EXPECT_TRUE(char_reg_type.IsCharTypes());
172  EXPECT_TRUE(char_reg_type.IsIntegralTypes());
173  EXPECT_FALSE(char_reg_type.IsFloatTypes());
174  EXPECT_FALSE(char_reg_type.IsLongTypes());
175  EXPECT_FALSE(char_reg_type.IsDoubleTypes());
176  EXPECT_TRUE(char_reg_type.IsArrayIndexTypes());
177  EXPECT_FALSE(char_reg_type.IsNonZeroReferenceTypes());
178
179  RegType& short_reg_type = cache.Short();
180  EXPECT_FALSE(short_reg_type.IsUndefined());
181  EXPECT_FALSE(short_reg_type.IsConflict());
182  EXPECT_FALSE(short_reg_type.IsZero());
183  EXPECT_FALSE(short_reg_type.IsOne());
184  EXPECT_FALSE(short_reg_type.IsLongConstant());
185  EXPECT_FALSE(short_reg_type.IsBoolean());
186  EXPECT_FALSE(short_reg_type.IsByte());
187  EXPECT_FALSE(short_reg_type.IsChar());
188  EXPECT_TRUE(short_reg_type.IsShort());
189  EXPECT_FALSE(short_reg_type.IsInteger());
190  EXPECT_FALSE(short_reg_type.IsLong());
191  EXPECT_FALSE(short_reg_type.IsFloat());
192  EXPECT_FALSE(short_reg_type.IsDouble());
193  EXPECT_FALSE(short_reg_type.IsReference());
194  EXPECT_FALSE(short_reg_type.IsLowHalf());
195  EXPECT_FALSE(short_reg_type.IsHighHalf());
196  EXPECT_FALSE(short_reg_type.IsLongOrDoubleTypes());
197  EXPECT_FALSE(short_reg_type.IsReferenceTypes());
198  EXPECT_TRUE(short_reg_type.IsCategory1Types());
199  EXPECT_FALSE(short_reg_type.IsCategory2Types());
200  EXPECT_FALSE(short_reg_type.IsBooleanTypes());
201  EXPECT_FALSE(short_reg_type.IsByteTypes());
202  EXPECT_TRUE(short_reg_type.IsShortTypes());
203  EXPECT_FALSE(short_reg_type.IsCharTypes());
204  EXPECT_TRUE(short_reg_type.IsIntegralTypes());
205  EXPECT_FALSE(short_reg_type.IsFloatTypes());
206  EXPECT_FALSE(short_reg_type.IsLongTypes());
207  EXPECT_FALSE(short_reg_type.IsDoubleTypes());
208  EXPECT_TRUE(short_reg_type.IsArrayIndexTypes());
209  EXPECT_FALSE(short_reg_type.IsNonZeroReferenceTypes());
210
211  RegType& int_reg_type = cache.Integer();
212  EXPECT_FALSE(int_reg_type.IsUndefined());
213  EXPECT_FALSE(int_reg_type.IsConflict());
214  EXPECT_FALSE(int_reg_type.IsZero());
215  EXPECT_FALSE(int_reg_type.IsOne());
216  EXPECT_FALSE(int_reg_type.IsLongConstant());
217  EXPECT_FALSE(int_reg_type.IsBoolean());
218  EXPECT_FALSE(int_reg_type.IsByte());
219  EXPECT_FALSE(int_reg_type.IsChar());
220  EXPECT_FALSE(int_reg_type.IsShort());
221  EXPECT_TRUE(int_reg_type.IsInteger());
222  EXPECT_FALSE(int_reg_type.IsLong());
223  EXPECT_FALSE(int_reg_type.IsFloat());
224  EXPECT_FALSE(int_reg_type.IsDouble());
225  EXPECT_FALSE(int_reg_type.IsReference());
226  EXPECT_FALSE(int_reg_type.IsLowHalf());
227  EXPECT_FALSE(int_reg_type.IsHighHalf());
228  EXPECT_FALSE(int_reg_type.IsLongOrDoubleTypes());
229  EXPECT_FALSE(int_reg_type.IsReferenceTypes());
230  EXPECT_TRUE(int_reg_type.IsCategory1Types());
231  EXPECT_FALSE(int_reg_type.IsCategory2Types());
232  EXPECT_FALSE(int_reg_type.IsBooleanTypes());
233  EXPECT_FALSE(int_reg_type.IsByteTypes());
234  EXPECT_FALSE(int_reg_type.IsShortTypes());
235  EXPECT_FALSE(int_reg_type.IsCharTypes());
236  EXPECT_TRUE(int_reg_type.IsIntegralTypes());
237  EXPECT_FALSE(int_reg_type.IsFloatTypes());
238  EXPECT_FALSE(int_reg_type.IsLongTypes());
239  EXPECT_FALSE(int_reg_type.IsDoubleTypes());
240  EXPECT_TRUE(int_reg_type.IsArrayIndexTypes());
241  EXPECT_FALSE(int_reg_type.IsNonZeroReferenceTypes());
242
243  RegType& long_reg_type = cache.LongLo();
244  EXPECT_FALSE(long_reg_type.IsUndefined());
245  EXPECT_FALSE(long_reg_type.IsConflict());
246  EXPECT_FALSE(long_reg_type.IsZero());
247  EXPECT_FALSE(long_reg_type.IsOne());
248  EXPECT_FALSE(long_reg_type.IsLongConstant());
249  EXPECT_FALSE(long_reg_type.IsBoolean());
250  EXPECT_FALSE(long_reg_type.IsByte());
251  EXPECT_FALSE(long_reg_type.IsChar());
252  EXPECT_FALSE(long_reg_type.IsShort());
253  EXPECT_FALSE(long_reg_type.IsInteger());
254  EXPECT_TRUE(long_reg_type.IsLong());
255  EXPECT_FALSE(long_reg_type.IsFloat());
256  EXPECT_FALSE(long_reg_type.IsDouble());
257  EXPECT_FALSE(long_reg_type.IsReference());
258  EXPECT_TRUE(long_reg_type.IsLowHalf());
259  EXPECT_FALSE(long_reg_type.IsHighHalf());
260  EXPECT_TRUE(long_reg_type.IsLongOrDoubleTypes());
261  EXPECT_FALSE(long_reg_type.IsReferenceTypes());
262  EXPECT_FALSE(long_reg_type.IsCategory1Types());
263  EXPECT_TRUE(long_reg_type.IsCategory2Types());
264  EXPECT_FALSE(long_reg_type.IsBooleanTypes());
265  EXPECT_FALSE(long_reg_type.IsByteTypes());
266  EXPECT_FALSE(long_reg_type.IsShortTypes());
267  EXPECT_FALSE(long_reg_type.IsCharTypes());
268  EXPECT_FALSE(long_reg_type.IsIntegralTypes());
269  EXPECT_FALSE(long_reg_type.IsFloatTypes());
270  EXPECT_TRUE(long_reg_type.IsLongTypes());
271  EXPECT_FALSE(long_reg_type.IsDoubleTypes());
272  EXPECT_FALSE(long_reg_type.IsArrayIndexTypes());
273  EXPECT_FALSE(long_reg_type.IsNonZeroReferenceTypes());
274
275  RegType& float_reg_type = cache.Float();
276  EXPECT_FALSE(float_reg_type.IsUndefined());
277  EXPECT_FALSE(float_reg_type.IsConflict());
278  EXPECT_FALSE(float_reg_type.IsZero());
279  EXPECT_FALSE(float_reg_type.IsOne());
280  EXPECT_FALSE(float_reg_type.IsLongConstant());
281  EXPECT_FALSE(float_reg_type.IsBoolean());
282  EXPECT_FALSE(float_reg_type.IsByte());
283  EXPECT_FALSE(float_reg_type.IsChar());
284  EXPECT_FALSE(float_reg_type.IsShort());
285  EXPECT_FALSE(float_reg_type.IsInteger());
286  EXPECT_FALSE(float_reg_type.IsLong());
287  EXPECT_TRUE(float_reg_type.IsFloat());
288  EXPECT_FALSE(float_reg_type.IsDouble());
289  EXPECT_FALSE(float_reg_type.IsReference());
290  EXPECT_FALSE(float_reg_type.IsLowHalf());
291  EXPECT_FALSE(float_reg_type.IsHighHalf());
292  EXPECT_FALSE(float_reg_type.IsLongOrDoubleTypes());
293  EXPECT_FALSE(float_reg_type.IsReferenceTypes());
294  EXPECT_TRUE(float_reg_type.IsCategory1Types());
295  EXPECT_FALSE(float_reg_type.IsCategory2Types());
296  EXPECT_FALSE(float_reg_type.IsBooleanTypes());
297  EXPECT_FALSE(float_reg_type.IsByteTypes());
298  EXPECT_FALSE(float_reg_type.IsShortTypes());
299  EXPECT_FALSE(float_reg_type.IsCharTypes());
300  EXPECT_FALSE(float_reg_type.IsIntegralTypes());
301  EXPECT_TRUE(float_reg_type.IsFloatTypes());
302  EXPECT_FALSE(float_reg_type.IsLongTypes());
303  EXPECT_FALSE(float_reg_type.IsDoubleTypes());
304  EXPECT_FALSE(float_reg_type.IsArrayIndexTypes());
305  EXPECT_FALSE(float_reg_type.IsNonZeroReferenceTypes());
306
307  RegType& double_reg_type = cache.DoubleLo();
308  EXPECT_FALSE(double_reg_type.IsUndefined());
309  EXPECT_FALSE(double_reg_type.IsConflict());
310  EXPECT_FALSE(double_reg_type.IsZero());
311  EXPECT_FALSE(double_reg_type.IsOne());
312  EXPECT_FALSE(double_reg_type.IsLongConstant());
313  EXPECT_FALSE(double_reg_type.IsBoolean());
314  EXPECT_FALSE(double_reg_type.IsByte());
315  EXPECT_FALSE(double_reg_type.IsChar());
316  EXPECT_FALSE(double_reg_type.IsShort());
317  EXPECT_FALSE(double_reg_type.IsInteger());
318  EXPECT_FALSE(double_reg_type.IsLong());
319  EXPECT_FALSE(double_reg_type.IsFloat());
320  EXPECT_TRUE(double_reg_type.IsDouble());
321  EXPECT_FALSE(double_reg_type.IsReference());
322  EXPECT_TRUE(double_reg_type.IsLowHalf());
323  EXPECT_FALSE(double_reg_type.IsHighHalf());
324  EXPECT_TRUE(double_reg_type.IsLongOrDoubleTypes());
325  EXPECT_FALSE(double_reg_type.IsReferenceTypes());
326  EXPECT_FALSE(double_reg_type.IsCategory1Types());
327  EXPECT_TRUE(double_reg_type.IsCategory2Types());
328  EXPECT_FALSE(double_reg_type.IsBooleanTypes());
329  EXPECT_FALSE(double_reg_type.IsByteTypes());
330  EXPECT_FALSE(double_reg_type.IsShortTypes());
331  EXPECT_FALSE(double_reg_type.IsCharTypes());
332  EXPECT_FALSE(double_reg_type.IsIntegralTypes());
333  EXPECT_FALSE(double_reg_type.IsFloatTypes());
334  EXPECT_FALSE(double_reg_type.IsLongTypes());
335  EXPECT_TRUE(double_reg_type.IsDoubleTypes());
336  EXPECT_FALSE(double_reg_type.IsArrayIndexTypes());
337  EXPECT_FALSE(double_reg_type.IsNonZeroReferenceTypes());
338}
339
340class RegTypeReferenceTest : public CommonRuntimeTest {};
341
342TEST_F(RegTypeReferenceTest, JavalangObjectImprecise) {
343  // Tests matching precisions. A reference type that was created precise doesn't
344  // match the one that is imprecise.
345  ScopedObjectAccess soa(Thread::Current());
346  RegTypeCache cache(true);
347  RegType& imprecise_obj = cache.JavaLangObject(false);
348  RegType& precise_obj = cache.JavaLangObject(true);
349  RegType& precise_obj_2 = cache.FromDescriptor(NULL, "Ljava/lang/Object;", true);
350
351  EXPECT_TRUE(precise_obj.Equals(precise_obj_2));
352  EXPECT_FALSE(imprecise_obj.Equals(precise_obj));
353  EXPECT_FALSE(imprecise_obj.Equals(precise_obj));
354  EXPECT_FALSE(imprecise_obj.Equals(precise_obj_2));
355}
356
357TEST_F(RegTypeReferenceTest, UnresolvedType) {
358  // Tests creating unresolved types. Miss for the first time asking the cache and
359  // a hit second time.
360  ScopedObjectAccess soa(Thread::Current());
361  RegTypeCache cache(true);
362  RegType& ref_type_0 = cache.FromDescriptor(NULL, "Ljava/lang/DoesNotExist;", true);
363  EXPECT_TRUE(ref_type_0.IsUnresolvedReference());
364  EXPECT_TRUE(ref_type_0.IsNonZeroReferenceTypes());
365
366  RegType& ref_type_1 = cache.FromDescriptor(NULL, "Ljava/lang/DoesNotExist;", true);
367  EXPECT_TRUE(ref_type_0.Equals(ref_type_1));
368
369  RegType& unresolved_super_class =  cache.FromUnresolvedSuperClass(ref_type_0);
370  EXPECT_TRUE(unresolved_super_class.IsUnresolvedSuperClass());
371  EXPECT_TRUE(unresolved_super_class.IsNonZeroReferenceTypes());
372}
373
374TEST_F(RegTypeReferenceTest, UnresolvedUnintializedType) {
375  // Tests creating types uninitialized types from unresolved types.
376  ScopedObjectAccess soa(Thread::Current());
377  RegTypeCache cache(true);
378  RegType& ref_type_0 = cache.FromDescriptor(NULL, "Ljava/lang/DoesNotExist;", true);
379  EXPECT_TRUE(ref_type_0.IsUnresolvedReference());
380  RegType& ref_type = cache.FromDescriptor(NULL, "Ljava/lang/DoesNotExist;", true);
381  EXPECT_TRUE(ref_type_0.Equals(ref_type));
382  // Create an uninitialized type of this unresolved type
383  RegType& unresolved_unintialised = cache.Uninitialized(ref_type, 1101ull);
384  EXPECT_TRUE(unresolved_unintialised.IsUnresolvedAndUninitializedReference());
385  EXPECT_TRUE(unresolved_unintialised.IsUninitializedTypes());
386  EXPECT_TRUE(unresolved_unintialised.IsNonZeroReferenceTypes());
387  // Create an uninitialized type of this unresolved type with different  PC
388  RegType& ref_type_unresolved_unintialised_1 =  cache.Uninitialized(ref_type, 1102ull);
389  EXPECT_TRUE(unresolved_unintialised.IsUnresolvedAndUninitializedReference());
390  EXPECT_FALSE(unresolved_unintialised.Equals(ref_type_unresolved_unintialised_1));
391  // Create an uninitialized type of this unresolved type with the same PC
392  RegType& unresolved_unintialised_2 = cache.Uninitialized(ref_type, 1101ull);
393  EXPECT_TRUE(unresolved_unintialised.Equals(unresolved_unintialised_2));
394}
395
396TEST_F(RegTypeReferenceTest, Dump) {
397  // Tests types for proper Dump messages.
398  ScopedObjectAccess soa(Thread::Current());
399  RegTypeCache cache(true);
400  RegType& unresolved_ref = cache.FromDescriptor(NULL, "Ljava/lang/DoesNotExist;", true);
401  RegType& unresolved_ref_another = cache.FromDescriptor(NULL, "Ljava/lang/DoesNotExistEither;", true);
402  RegType& resolved_ref = cache.JavaLangString();
403  RegType& resolved_unintialiesd = cache.Uninitialized(resolved_ref, 10);
404  RegType& unresolved_unintialized = cache.Uninitialized(unresolved_ref, 12);
405  RegType& unresolved_merged = cache.FromUnresolvedMerge(unresolved_ref, unresolved_ref_another);
406
407  std::string expected = "Unresolved Reference: java.lang.DoesNotExist";
408  EXPECT_EQ(expected, unresolved_ref.Dump());
409  expected = "Precise Reference: java.lang.String";
410  EXPECT_EQ(expected, resolved_ref.Dump());
411  expected ="Uninitialized Reference: java.lang.String Allocation PC: 10";
412  EXPECT_EQ(expected, resolved_unintialiesd.Dump());
413  expected = "Unresolved And Uninitialized Reference: java.lang.DoesNotExist Allocation PC: 12";
414  EXPECT_EQ(expected, unresolved_unintialized.Dump());
415  expected = "UnresolvedMergedReferences(Unresolved Reference: java.lang.DoesNotExist, Unresolved Reference: java.lang.DoesNotExistEither)";
416  EXPECT_EQ(expected, unresolved_merged.Dump());
417}
418
419TEST_F(RegTypeReferenceTest, JavalangString) {
420  // Add a class to the cache then look for the same class and make sure it is  a
421  // Hit the second time. Then check for the same effect when using
422  // The JavaLangObject method instead of FromDescriptor. String class is final.
423  ScopedObjectAccess soa(Thread::Current());
424  RegTypeCache cache(true);
425  RegType& ref_type = cache.JavaLangString();
426  RegType& ref_type_2 = cache.JavaLangString();
427  RegType& ref_type_3 = cache.FromDescriptor(NULL, "Ljava/lang/String;", true);
428
429  EXPECT_TRUE(ref_type.Equals(ref_type_2));
430  EXPECT_TRUE(ref_type_2.Equals(ref_type_3));
431  EXPECT_TRUE(ref_type.IsPreciseReference());
432
433  // Create an uninitialized type out of this:
434  RegType& ref_type_unintialized = cache.Uninitialized(ref_type, 0110ull);
435  EXPECT_TRUE(ref_type_unintialized.IsUninitializedReference());
436  EXPECT_FALSE(ref_type_unintialized.IsUnresolvedAndUninitializedReference());
437}
438
439TEST_F(RegTypeReferenceTest, JavalangObject) {
440  // Add a class to the cache then look for the same class and make sure it is  a
441  // Hit the second time. Then I am checking for the same effect when using
442  // The JavaLangObject method instead of FromDescriptor. Object Class in not final.
443  ScopedObjectAccess soa(Thread::Current());
444  RegTypeCache cache(true);
445  RegType& ref_type = cache.JavaLangObject(true);
446  RegType& ref_type_2 = cache.JavaLangObject(true);
447  RegType& ref_type_3 = cache.FromDescriptor(NULL, "Ljava/lang/Object;", true);
448
449  EXPECT_TRUE(ref_type.Equals(ref_type_2));
450  EXPECT_TRUE(ref_type_3.Equals(ref_type_2));
451  EXPECT_EQ(ref_type.GetId(), ref_type_3.GetId());
452}
453TEST_F(RegTypeReferenceTest, Merging) {
454  // Tests merging logic
455  // String and object , LUB is object.
456  ScopedObjectAccess soa(Thread::Current());
457  RegTypeCache cache_new(true);
458  RegType& string = cache_new.JavaLangString();
459  RegType& Object = cache_new.JavaLangObject(true);
460  EXPECT_TRUE(string.Merge(Object, &cache_new).IsJavaLangObject());
461  // Merge two unresolved types.
462  RegType& ref_type_0 = cache_new.FromDescriptor(NULL, "Ljava/lang/DoesNotExist;", true);
463  EXPECT_TRUE(ref_type_0.IsUnresolvedReference());
464  RegType& ref_type_1 = cache_new.FromDescriptor(NULL, "Ljava/lang/DoesNotExistToo;", true);
465  EXPECT_FALSE(ref_type_0.Equals(ref_type_1));
466
467  RegType& merged = ref_type_1.Merge(ref_type_0, &cache_new);
468  EXPECT_TRUE(merged.IsUnresolvedMergedReference());
469
470  std::set<uint16_t> merged_ids = (down_cast<UnresolvedMergedType*>(&merged))->GetMergedTypes();
471  EXPECT_EQ(ref_type_0.GetId(), *(merged_ids.begin()));
472  EXPECT_EQ(ref_type_1.GetId(), *((++merged_ids.begin())));
473}
474
475TEST_F(RegTypeTest, MergingFloat) {
476  // Testing merging logic with float and float constants.
477  ScopedObjectAccess soa(Thread::Current());
478  RegTypeCache cache_new(true);
479
480  constexpr int32_t kTestConstantValue = 10;
481  RegType& float_type = cache_new.Float();
482  RegType& precise_cst = cache_new.FromCat1Const(kTestConstantValue, true);
483  RegType& imprecise_cst = cache_new.FromCat1Const(kTestConstantValue, false);
484  {
485    // float MERGE precise cst => float.
486    RegType& merged = float_type.Merge(precise_cst, &cache_new);
487    EXPECT_TRUE(merged.IsFloat());
488  }
489  {
490    // precise cst MERGE float => float.
491    RegType& merged = precise_cst.Merge(float_type, &cache_new);
492    EXPECT_TRUE(merged.IsFloat());
493  }
494  {
495    // float MERGE imprecise cst => float.
496    RegType& merged = float_type.Merge(imprecise_cst, &cache_new);
497    EXPECT_TRUE(merged.IsFloat());
498  }
499  {
500    // imprecise cst MERGE float => float.
501    RegType& merged = imprecise_cst.Merge(float_type, &cache_new);
502    EXPECT_TRUE(merged.IsFloat());
503  }
504}
505
506TEST_F(RegTypeTest, MergingLong) {
507  // Testing merging logic with long and long constants.
508  ScopedObjectAccess soa(Thread::Current());
509  RegTypeCache cache_new(true);
510
511  constexpr int32_t kTestConstantValue = 10;
512  RegType& long_lo_type = cache_new.LongLo();
513  RegType& long_hi_type = cache_new.LongHi();
514  RegType& precise_cst_lo = cache_new.FromCat2ConstLo(kTestConstantValue, true);
515  RegType& imprecise_cst_lo = cache_new.FromCat2ConstLo(kTestConstantValue, false);
516  RegType& precise_cst_hi = cache_new.FromCat2ConstHi(kTestConstantValue, true);
517  RegType& imprecise_cst_hi = cache_new.FromCat2ConstHi(kTestConstantValue, false);
518  {
519    // lo MERGE precise cst lo => lo.
520    RegType& merged = long_lo_type.Merge(precise_cst_lo, &cache_new);
521    EXPECT_TRUE(merged.IsLongLo());
522  }
523  {
524    // precise cst lo MERGE lo => lo.
525    RegType& merged = precise_cst_lo.Merge(long_lo_type, &cache_new);
526    EXPECT_TRUE(merged.IsLongLo());
527  }
528  {
529    // lo MERGE imprecise cst lo => lo.
530    RegType& merged = long_lo_type.Merge(imprecise_cst_lo, &cache_new);
531    EXPECT_TRUE(merged.IsLongLo());
532  }
533  {
534    // imprecise cst lo MERGE lo => lo.
535    RegType& merged = imprecise_cst_lo.Merge(long_lo_type, &cache_new);
536    EXPECT_TRUE(merged.IsLongLo());
537  }
538  {
539    // hi MERGE precise cst hi => hi.
540    RegType& merged = long_hi_type.Merge(precise_cst_hi, &cache_new);
541    EXPECT_TRUE(merged.IsLongHi());
542  }
543  {
544    // precise cst hi MERGE hi => hi.
545    RegType& merged = precise_cst_hi.Merge(long_hi_type, &cache_new);
546    EXPECT_TRUE(merged.IsLongHi());
547  }
548  {
549    // hi MERGE imprecise cst hi => hi.
550    RegType& merged = long_hi_type.Merge(imprecise_cst_hi, &cache_new);
551    EXPECT_TRUE(merged.IsLongHi());
552  }
553  {
554    // imprecise cst hi MERGE hi => hi.
555    RegType& merged = imprecise_cst_hi.Merge(long_hi_type, &cache_new);
556    EXPECT_TRUE(merged.IsLongHi());
557  }
558}
559
560TEST_F(RegTypeTest, MergingDouble) {
561  // Testing merging logic with double and double constants.
562  ScopedObjectAccess soa(Thread::Current());
563  RegTypeCache cache_new(true);
564
565  constexpr int32_t kTestConstantValue = 10;
566  RegType& double_lo_type = cache_new.DoubleLo();
567  RegType& double_hi_type = cache_new.DoubleHi();
568  RegType& precise_cst_lo = cache_new.FromCat2ConstLo(kTestConstantValue, true);
569  RegType& imprecise_cst_lo = cache_new.FromCat2ConstLo(kTestConstantValue, false);
570  RegType& precise_cst_hi = cache_new.FromCat2ConstHi(kTestConstantValue, true);
571  RegType& imprecise_cst_hi = cache_new.FromCat2ConstHi(kTestConstantValue, false);
572  {
573    // lo MERGE precise cst lo => lo.
574    RegType& merged = double_lo_type.Merge(precise_cst_lo, &cache_new);
575    EXPECT_TRUE(merged.IsDoubleLo());
576  }
577  {
578    // precise cst lo MERGE lo => lo.
579    RegType& merged = precise_cst_lo.Merge(double_lo_type, &cache_new);
580    EXPECT_TRUE(merged.IsDoubleLo());
581  }
582  {
583    // lo MERGE imprecise cst lo => lo.
584    RegType& merged = double_lo_type.Merge(imprecise_cst_lo, &cache_new);
585    EXPECT_TRUE(merged.IsDoubleLo());
586  }
587  {
588    // imprecise cst lo MERGE lo => lo.
589    RegType& merged = imprecise_cst_lo.Merge(double_lo_type, &cache_new);
590    EXPECT_TRUE(merged.IsDoubleLo());
591  }
592  {
593    // hi MERGE precise cst hi => hi.
594    RegType& merged = double_hi_type.Merge(precise_cst_hi, &cache_new);
595    EXPECT_TRUE(merged.IsDoubleHi());
596  }
597  {
598    // precise cst hi MERGE hi => hi.
599    RegType& merged = precise_cst_hi.Merge(double_hi_type, &cache_new);
600    EXPECT_TRUE(merged.IsDoubleHi());
601  }
602  {
603    // hi MERGE imprecise cst hi => hi.
604    RegType& merged = double_hi_type.Merge(imprecise_cst_hi, &cache_new);
605    EXPECT_TRUE(merged.IsDoubleHi());
606  }
607  {
608    // imprecise cst hi MERGE hi => hi.
609    RegType& merged = imprecise_cst_hi.Merge(double_hi_type, &cache_new);
610    EXPECT_TRUE(merged.IsDoubleHi());
611  }
612}
613
614TEST_F(RegTypeTest, ConstPrecision) {
615  // Tests creating primitive types types.
616  ScopedObjectAccess soa(Thread::Current());
617  RegTypeCache cache_new(true);
618  RegType& imprecise_const = cache_new.FromCat1Const(10, false);
619  RegType& precise_const = cache_new.FromCat1Const(10, true);
620
621  EXPECT_TRUE(imprecise_const.IsImpreciseConstant());
622  EXPECT_TRUE(precise_const.IsPreciseConstant());
623  EXPECT_FALSE(imprecise_const.Equals(precise_const));
624}
625
626}  // namespace verifier
627}  // namespace art
628