• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2015 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 #ifndef ART_COMPILER_OPTIMIZING_REFERENCE_TYPE_PROPAGATION_H_
18 #define ART_COMPILER_OPTIMIZING_REFERENCE_TYPE_PROPAGATION_H_
19 
20 #include "base/arena_containers.h"
21 #include "driver/dex_compilation_unit.h"
22 #include "handle_scope-inl.h"
23 #include "nodes.h"
24 #include "optimization.h"
25 #include "optimizing_compiler_stats.h"
26 
27 namespace art {
28 
29 /**
30  * Propagates reference types to instructions.
31  */
32 class ReferenceTypePropagation : public HOptimization {
33  public:
34   ReferenceTypePropagation(HGraph* graph,
35                            Handle<mirror::DexCache> hint_dex_cache,
36                            StackHandleScopeCollection* handles,
37                            bool is_first_run,
38                            const char* name = kReferenceTypePropagationPassName);
39 
40   // Visit a single instruction.
41   void Visit(HInstruction* instruction);
42 
43   void Run() OVERRIDE;
44 
45   static constexpr const char* kReferenceTypePropagationPassName = "reference_type_propagation";
46 
47  private:
48   class HandleCache {
49    public:
HandleCache(StackHandleScopeCollection * handles)50     explicit HandleCache(StackHandleScopeCollection* handles) : handles_(handles) { }
51 
52     template <typename T>
NewHandle(T * object)53     MutableHandle<T> NewHandle(T* object) SHARED_REQUIRES(Locks::mutator_lock_) {
54       return handles_->NewHandle(object);
55     }
56 
57     ReferenceTypeInfo::TypeHandle GetObjectClassHandle();
58     ReferenceTypeInfo::TypeHandle GetClassClassHandle();
59     ReferenceTypeInfo::TypeHandle GetStringClassHandle();
60     ReferenceTypeInfo::TypeHandle GetThrowableClassHandle();
61 
62    private:
63     StackHandleScopeCollection* handles_;
64 
65     ReferenceTypeInfo::TypeHandle object_class_handle_;
66     ReferenceTypeInfo::TypeHandle class_class_handle_;
67     ReferenceTypeInfo::TypeHandle string_class_handle_;
68     ReferenceTypeInfo::TypeHandle throwable_class_handle_;
69   };
70 
71   class RTPVisitor;
72 
73   void VisitPhi(HPhi* phi);
74   void VisitBasicBlock(HBasicBlock* block);
75   void UpdateBoundType(HBoundType* bound_type) SHARED_REQUIRES(Locks::mutator_lock_);
76   void UpdatePhi(HPhi* phi) SHARED_REQUIRES(Locks::mutator_lock_);
77   void BoundTypeForIfNotNull(HBasicBlock* block);
78   void BoundTypeForIfInstanceOf(HBasicBlock* block);
79   void ProcessWorklist();
80   void AddToWorklist(HInstruction* instr);
81   void AddDependentInstructionsToWorklist(HInstruction* instr);
82 
83   bool UpdateNullability(HInstruction* instr);
84   bool UpdateReferenceTypeInfo(HInstruction* instr);
85 
86   static void UpdateArrayGet(HArrayGet* instr, HandleCache* handle_cache)
87       SHARED_REQUIRES(Locks::mutator_lock_);
88 
89   ReferenceTypeInfo MergeTypes(const ReferenceTypeInfo& a, const ReferenceTypeInfo& b)
90       SHARED_REQUIRES(Locks::mutator_lock_);
91 
92   void ValidateTypes();
93 
94   // Note: hint_dex_cache_ is usually, but not necessarily, the dex cache associated with
95   // graph_->GetDexFile(). Since we may look up also in other dex files, it's used only
96   // as a hint, to reduce the number of calls to the costly ClassLinker::FindDexCache().
97   Handle<mirror::DexCache> hint_dex_cache_;
98   HandleCache handle_cache_;
99 
100   ArenaVector<HInstruction*> worklist_;
101 
102   // Whether this reference type propagation is the first run we are doing.
103   const bool is_first_run_;
104 
105   static constexpr size_t kDefaultWorklistSize = 8;
106 
107   friend class ReferenceTypePropagationTest;
108 
109   DISALLOW_COPY_AND_ASSIGN(ReferenceTypePropagation);
110 };
111 
112 }  // namespace art
113 
114 #endif  // ART_COMPILER_OPTIMIZING_REFERENCE_TYPE_PROPAGATION_H_
115