OLD | NEW |
---|---|
(Empty) | |
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 | |
3 // BSD-style license that can be found in the LICENSE file. | |
4 | |
5 #include "vm/optimizer.h" | |
6 | |
7 #include "vm/intermediate_language.h" | |
8 #include "vm/object.h" | |
9 | |
10 namespace dart { | |
11 | |
12 static bool CidTestResultsContains(const ZoneGrowableArray<intptr_t>& results, | |
13 intptr_t test_cid) { | |
14 for (intptr_t i = 0; i < results.length(); i += 2) { | |
15 if (results[i] == test_cid) return true; | |
16 } | |
17 return false; | |
18 } | |
19 | |
20 | |
21 static void TryAddTest(ZoneGrowableArray<intptr_t>* results, | |
22 intptr_t test_cid, | |
23 bool result) { | |
24 if (!CidTestResultsContains(*results, test_cid)) { | |
25 results->Add(test_cid); | |
26 results->Add(result); | |
27 } | |
28 } | |
29 | |
30 | |
31 // Used when we only need the positive result because we return false by | |
32 // default. | |
33 static void PurgeNegativeTestCidsEntries(ZoneGrowableArray<intptr_t>* results) { | |
34 int dest = 0; | |
35 for (intptr_t i = 0; i < results->length(); i += 2) { | |
Vyacheslav Egorov (Google)
2017/05/23 16:00:31
It feels like you can just start with i = dest = 1
erikcorry
2017/05/24 13:37:16
Done.
| |
36 // We can't purge the Smi entry at the beginning since it is used in the | |
37 // Smi check before the Cid is loaded. | |
38 if (results->At(i + 1) || results->At(i) == kSmiCid) { | |
Vyacheslav Egorov (Google)
2017/05/23 16:00:31
At(i + 1) != 0 - we don't use implicit intptr_t ->
erikcorry
2017/05/24 13:37:16
Done.
| |
39 (*results)[dest++] = results->At(i); | |
40 (*results)[dest++] = results->At(i + 1); | |
41 } | |
42 } | |
43 results->SetLength(dest); | |
44 } | |
45 | |
46 | |
47 // Tries to add cid tests to 'results' so that no deoptimization is | |
Vyacheslav Egorov (Google)
2017/05/23 16:00:32
Maybe move this comment to the header file?
erikcorry
2017/05/24 13:37:16
Done.
| |
48 // necessary for common number-related type tests. Unconditionally adds an | |
49 // entry for the Smi type to the start of the array. | |
50 // TODO(srdjan): Do also for other than numeric types. | |
Vyacheslav Egorov (Google)
2017/05/23 16:00:32
remove TODO(srdjan)
erikcorry
2017/05/23 18:24:40
Do you mean I should remove the whole line?
Is th
Vyacheslav Egorov (Google)
2017/05/23 18:33:15
I don't think srdjan is gonna do it. Also it is al
erikcorry
2017/05/23 18:35:09
OK I'll remove it, but the TODO was to handle non-
Vyacheslav Egorov (Google)
2017/05/23 18:36:13
Ooops. I misread it - but anyway if you want to ke
erikcorry
2017/05/24 13:37:16
Gone
| |
51 bool Optimizer::TryExpandTestCidsResult(ZoneGrowableArray<intptr_t>* results, | |
Vyacheslav Egorov (Google)
2017/05/23 16:00:32
I wonder if this should be using a better type tha
erikcorry
2017/05/24 13:37:16
It should, but I'd just like to fix the bug. Slig
| |
52 const AbstractType& type, | |
53 bool int_type_only) { | |
54 ASSERT(results->length() >= 2); // At least on entry. | |
55 const ClassTable& class_table = *Isolate::Current()->class_table(); | |
56 if ((*results)[0] != kSmiCid) { | |
57 const Class& cls = Class::Handle(class_table.At(kSmiCid)); | |
58 const Class& type_class = Class::Handle(type.type_class()); | |
59 const bool smi_is_subtype = | |
60 cls.IsSubtypeOf(Object::null_type_arguments(), type_class, | |
61 Object::null_type_arguments(), NULL, NULL, Heap::kOld); | |
62 results->Add((*results)[results->length() - 2]); | |
63 results->Add((*results)[results->length() - 2]); | |
64 for (intptr_t i = results->length() - 3; i > 1; --i) { | |
65 (*results)[i] = (*results)[i - 2]; | |
66 } | |
67 (*results)[0] = kSmiCid; | |
68 (*results)[1] = smi_is_subtype; | |
69 } | |
70 | |
71 ASSERT(type.IsInstantiated() && !type.IsMalformedOrMalbounded()); | |
72 ASSERT(results->length() >= 2); | |
73 if (type.IsSmiType() && !int_type_only) { | |
74 ASSERT((*results)[0] == kSmiCid); | |
75 PurgeNegativeTestCidsEntries(results); | |
76 return false; | |
77 } else if (type.IsIntType()) { | |
78 ASSERT((*results)[0] == kSmiCid); | |
79 TryAddTest(results, kMintCid, true); | |
80 TryAddTest(results, kBigintCid, true); | |
81 // Cannot deoptimize since all tests returning true have been added. | |
82 PurgeNegativeTestCidsEntries(results); | |
83 return false; | |
84 } else if (type.IsNumberType() && !int_type_only) { | |
85 ASSERT((*results)[0] == kSmiCid); | |
86 TryAddTest(results, kMintCid, true); | |
87 TryAddTest(results, kBigintCid, true); | |
88 TryAddTest(results, kDoubleCid, true); | |
89 PurgeNegativeTestCidsEntries(results); | |
90 return false; | |
91 } else if (type.IsDoubleType() && !int_type_only) { | |
92 ASSERT((*results)[0] == kSmiCid); | |
93 TryAddTest(results, kDoubleCid, true); | |
94 PurgeNegativeTestCidsEntries(results); | |
95 return false; | |
96 } | |
97 return true; // May deoptimize since we have not identified all 'true' tests. | |
98 } | |
99 | |
100 } // namespace dart | |
OLD | NEW |