1 | // Copyright (c) 2012, 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 | #ifndef RUNTIME_VM_COMPILER_CHA_H_ |
6 | #define RUNTIME_VM_COMPILER_CHA_H_ |
7 | |
8 | #if defined(DART_PRECOMPILED_RUNTIME) |
9 | #error "AOT runtime should not use compiler sources (including header files)" |
10 | #endif // defined(DART_PRECOMPILED_RUNTIME) |
11 | |
12 | #include "vm/allocation.h" |
13 | #include "vm/growable_array.h" |
14 | #include "vm/thread.h" |
15 | |
16 | namespace dart { |
17 | |
18 | class Class; |
19 | class CompileType; |
20 | class Function; |
21 | template <typename T> |
22 | class ZoneGrowableArray; |
23 | class String; |
24 | |
25 | class CHA : public ValueObject { |
26 | public: |
27 | explicit CHA(Thread* thread) |
28 | : thread_(thread), guarded_classes_(thread->zone(), 1) {} |
29 | |
30 | // Returns true if the class has subclasses. |
31 | static bool HasSubclasses(const Class& cls); |
32 | bool HasSubclasses(intptr_t cid) const; |
33 | |
34 | // Collect the concrete subclasses of 'cls' into 'class_ids'. Return true if |
35 | // the result is valid (may be invalid because we don't track the subclasses |
36 | // of classes allocated in the VM isolate or class Object). |
37 | static bool ConcreteSubclasses(const Class& cls, |
38 | GrowableArray<intptr_t>* class_ids); |
39 | |
40 | // Return true if the class is implemented by some other class. |
41 | static bool IsImplemented(const Class& cls); |
42 | |
43 | // Returns true if any subclass of 'cls' contains the function. |
44 | // If no override was found subclass_count would contain total count of |
45 | // finalized subclasses that CHA looked at. |
46 | // This count will be used to validate CHA decision before installing |
47 | // optimized code compiled in background. |
48 | bool HasOverride(const Class& cls, |
49 | const String& function_name, |
50 | intptr_t* subclass_count); |
51 | |
52 | // Adds class 'cls' to the list of guarded classes, deoptimization occurs |
53 | // if any of those classes gets subclassed through later loaded/finalized |
54 | // libraries. Only classes that were used for CHA optimizations are added. |
55 | void AddToGuardedClasses(const Class& cls, intptr_t subclass_count); |
56 | |
57 | // When compiling in background we need to check that no new finalized |
58 | // subclasses were added to guarded classes. |
59 | bool IsConsistentWithCurrentHierarchy() const; |
60 | |
61 | void RegisterDependencies(const Code& code) const; |
62 | |
63 | // Used for testing. |
64 | bool IsGuardedClass(intptr_t cid) const; |
65 | |
66 | private: |
67 | Thread* thread_; |
68 | |
69 | struct GuardedClassInfo { |
70 | Class* cls; |
71 | |
72 | // Number of finalized subclasses that this class had at the moment |
73 | // when CHA made the first decision based on this class. |
74 | // Used to validate correctness of background compilation: if |
75 | // any subclasses were added we will discard compiled code. |
76 | intptr_t subclass_count; |
77 | }; |
78 | |
79 | GrowableArray<GuardedClassInfo> guarded_classes_; |
80 | }; |
81 | |
82 | } // namespace dart |
83 | |
84 | #endif // RUNTIME_VM_COMPILER_CHA_H_ |
85 | |