OLD | NEW |
1 // Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 #include "vm/optimizer.h" | 5 #include "vm/optimizer.h" |
6 | 6 |
7 #include "vm/intermediate_language.h" | 7 #include "vm/intermediate_language.h" |
8 #include "vm/object.h" | 8 #include "vm/object.h" |
9 | 9 |
10 namespace dart { | 10 namespace dart { |
11 | 11 |
12 static bool CidTestResultsContains(const ZoneGrowableArray<intptr_t>& results, | 12 static bool CidTestResultsContains(const ZoneGrowableArray<intptr_t>& results, |
13 intptr_t test_cid) { | 13 intptr_t test_cid) { |
14 for (intptr_t i = 0; i < results.length(); i += 2) { | 14 for (intptr_t i = 0; i < results.length(); i += 2) { |
15 if (results[i] == test_cid) return true; | 15 if (results[i] == test_cid) return true; |
16 } | 16 } |
17 return false; | 17 return false; |
18 } | 18 } |
19 | 19 |
20 | |
21 static void TryAddTest(ZoneGrowableArray<intptr_t>* results, | 20 static void TryAddTest(ZoneGrowableArray<intptr_t>* results, |
22 intptr_t test_cid, | 21 intptr_t test_cid, |
23 bool result) { | 22 bool result) { |
24 if (!CidTestResultsContains(*results, test_cid)) { | 23 if (!CidTestResultsContains(*results, test_cid)) { |
25 results->Add(test_cid); | 24 results->Add(test_cid); |
26 results->Add(result); | 25 results->Add(result); |
27 } | 26 } |
28 } | 27 } |
29 | 28 |
30 | |
31 // Used when we only need the positive result because we return false by | 29 // Used when we only need the positive result because we return false by |
32 // default. | 30 // default. |
33 static void PurgeNegativeTestCidsEntries(ZoneGrowableArray<intptr_t>* results) { | 31 static void PurgeNegativeTestCidsEntries(ZoneGrowableArray<intptr_t>* results) { |
34 // We can't purge the Smi entry at the beginning since it is used in the | 32 // We can't purge the Smi entry at the beginning since it is used in the |
35 // Smi check before the Cid is loaded. | 33 // Smi check before the Cid is loaded. |
36 int dest = 2; | 34 int dest = 2; |
37 for (intptr_t i = 2; i < results->length(); i += 2) { | 35 for (intptr_t i = 2; i < results->length(); i += 2) { |
38 if (results->At(i + 1) != 0) { | 36 if (results->At(i + 1) != 0) { |
39 (*results)[dest++] = results->At(i); | 37 (*results)[dest++] = results->At(i); |
40 (*results)[dest++] = results->At(i + 1); | 38 (*results)[dest++] = results->At(i + 1); |
41 } | 39 } |
42 } | 40 } |
43 results->SetLength(dest); | 41 results->SetLength(dest); |
44 } | 42 } |
45 | 43 |
46 | |
47 bool Optimizer::SpecializeTestCidsForNumericTypes( | 44 bool Optimizer::SpecializeTestCidsForNumericTypes( |
48 ZoneGrowableArray<intptr_t>* results, | 45 ZoneGrowableArray<intptr_t>* results, |
49 const AbstractType& type) { | 46 const AbstractType& type) { |
50 ASSERT(results->length() >= 2); // At least on entry. | 47 ASSERT(results->length() >= 2); // At least on entry. |
51 const ClassTable& class_table = *Isolate::Current()->class_table(); | 48 const ClassTable& class_table = *Isolate::Current()->class_table(); |
52 if ((*results)[0] != kSmiCid) { | 49 if ((*results)[0] != kSmiCid) { |
53 const Class& cls = Class::Handle(class_table.At(kSmiCid)); | 50 const Class& cls = Class::Handle(class_table.At(kSmiCid)); |
54 const Class& type_class = Class::Handle(type.type_class()); | 51 const Class& type_class = Class::Handle(type.type_class()); |
55 const bool smi_is_subtype = | 52 const bool smi_is_subtype = |
56 cls.IsSubtypeOf(Object::null_type_arguments(), type_class, | 53 cls.IsSubtypeOf(Object::null_type_arguments(), type_class, |
(...skipping 30 matching lines...) Expand all Loading... |
87 } else if (type.IsDoubleType()) { | 84 } else if (type.IsDoubleType()) { |
88 ASSERT((*results)[0] == kSmiCid); | 85 ASSERT((*results)[0] == kSmiCid); |
89 TryAddTest(results, kDoubleCid, true); | 86 TryAddTest(results, kDoubleCid, true); |
90 PurgeNegativeTestCidsEntries(results); | 87 PurgeNegativeTestCidsEntries(results); |
91 return false; | 88 return false; |
92 } | 89 } |
93 return true; // May deoptimize since we have not identified all 'true' tests. | 90 return true; // May deoptimize since we have not identified all 'true' tests. |
94 } | 91 } |
95 | 92 |
96 } // namespace dart | 93 } // namespace dart |
OLD | NEW |