Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(724)

Side by Side Diff: runtime/vm/optimizer.cc

Issue 2904543002: Fix misoptimization of 'is' test (Closed)
Patch Set: Remove inadvertent change Created 3 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698