blob: d36d59270853c903272654a5c8a41620081e9629 [file] [log] [blame]
Calin Juravle10e244f2015-01-26 18:54:32 +00001/*
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
Vladimir Marko2aaa4b52015-09-17 17:03:26 +010020#include "base/arena_containers.h"
Vladimir Marko009d1662017-10-10 13:21:15 +010021#include "mirror/class-inl.h"
Calin Juravle10e244f2015-01-26 18:54:32 +000022#include "nodes.h"
Mathieu Chartier3398c782016-09-30 10:27:43 -070023#include "obj_ptr.h"
Calin Juravle10e244f2015-01-26 18:54:32 +000024#include "optimization.h"
25
26namespace art {
27
28/**
29 * Propagates reference types to instructions.
Calin Juravle10e244f2015-01-26 18:54:32 +000030 */
Calin Juravle6c0c4f22015-06-12 15:40:42 +000031class ReferenceTypePropagation : public HOptimization {
Calin Juravle10e244f2015-01-26 18:54:32 +000032 public:
Calin Juravlea5ae3c32015-07-28 14:40:50 +000033 ReferenceTypePropagation(HGraph* graph,
Vladimir Marko8d6768d2017-03-14 10:13:21 +000034 Handle<mirror::ClassLoader> class_loader,
Vladimir Marko456307a2016-04-19 14:12:13 +000035 Handle<mirror::DexCache> hint_dex_cache,
Mathieu Chartiere8a3c572016-10-11 16:52:17 -070036 VariableSizedHandleScope* handles,
Nicolas Geoffrayd9994f02016-02-11 17:35:55 +000037 bool is_first_run,
Calin Juravle2e768302015-07-28 14:41:11 +000038 const char* name = kReferenceTypePropagationPassName);
Calin Juravle10e244f2015-01-26 18:54:32 +000039
Vladimir Markobe10e8e2016-01-22 12:09:44 +000040 // Visit a single instruction.
41 void Visit(HInstruction* instruction);
42
Aart Bik24773202018-04-26 10:28:51 -070043 bool Run() OVERRIDE;
Calin Juravle10e244f2015-01-26 18:54:32 +000044
David Brazdil94ab38f2016-06-21 17:48:19 +010045 // Returns true if klass is admissible to the propagation: non-null and resolved.
46 // For an array type, we also check if the component type is admissible.
Vladimir Markob45528c2017-07-27 14:14:28 +010047 static bool IsAdmissible(ObjPtr<mirror::Class> klass) REQUIRES_SHARED(Locks::mutator_lock_) {
David Brazdil94ab38f2016-06-21 17:48:19 +010048 return klass != nullptr &&
49 klass->IsResolved() &&
50 (!klass->IsArrayClass() || IsAdmissible(klass->GetComponentType()));
51 }
52
Andreas Gampe7c3952f2015-02-19 18:21:24 -080053 static constexpr const char* kReferenceTypePropagationPassName = "reference_type_propagation";
54
Mads Ager16e52892017-07-14 13:11:37 +020055 // Fix the reference type for an instruction whose inputs have changed.
56 // For a select instruction, the reference types of the inputs are merged
57 // and the resulting reference type is set on the select instruction.
58 static void FixUpInstructionType(HInstruction* instruction,
59 VariableSizedHandleScope* handle_scope);
60
Calin Juravle10e244f2015-01-26 18:54:32 +000061 private:
Vladimir Marko7d1fbf32016-01-26 15:01:12 +000062 class HandleCache {
63 public:
Mathieu Chartiere8a3c572016-10-11 16:52:17 -070064 explicit HandleCache(VariableSizedHandleScope* handles) : handles_(handles) { }
Vladimir Marko7d1fbf32016-01-26 15:01:12 +000065
66 template <typename T>
Andreas Gampebdf7f1c2016-08-30 16:38:47 -070067 MutableHandle<T> NewHandle(T* object) REQUIRES_SHARED(Locks::mutator_lock_) {
Vladimir Marko7d1fbf32016-01-26 15:01:12 +000068 return handles_->NewHandle(object);
69 }
70
Mathieu Chartier3398c782016-09-30 10:27:43 -070071 template <typename T>
72 MutableHandle<T> NewHandle(ObjPtr<T> object) REQUIRES_SHARED(Locks::mutator_lock_) {
73 return handles_->NewHandle(object);
74 }
75
Vladimir Marko7d1fbf32016-01-26 15:01:12 +000076 ReferenceTypeInfo::TypeHandle GetObjectClassHandle();
77 ReferenceTypeInfo::TypeHandle GetClassClassHandle();
Orion Hodsondbaa5c72018-05-10 08:22:46 +010078 ReferenceTypeInfo::TypeHandle GetMethodHandleClassHandle();
Orion Hodson18259d72018-04-12 11:18:23 +010079 ReferenceTypeInfo::TypeHandle GetMethodTypeClassHandle();
Vladimir Marko7d1fbf32016-01-26 15:01:12 +000080 ReferenceTypeInfo::TypeHandle GetStringClassHandle();
81 ReferenceTypeInfo::TypeHandle GetThrowableClassHandle();
82
83 private:
Mathieu Chartiere8a3c572016-10-11 16:52:17 -070084 VariableSizedHandleScope* handles_;
Vladimir Marko7d1fbf32016-01-26 15:01:12 +000085
86 ReferenceTypeInfo::TypeHandle object_class_handle_;
87 ReferenceTypeInfo::TypeHandle class_class_handle_;
Orion Hodsondbaa5c72018-05-10 08:22:46 +010088 ReferenceTypeInfo::TypeHandle method_handle_class_handle_;
Orion Hodson18259d72018-04-12 11:18:23 +010089 ReferenceTypeInfo::TypeHandle method_type_class_handle_;
Vladimir Marko7d1fbf32016-01-26 15:01:12 +000090 ReferenceTypeInfo::TypeHandle string_class_handle_;
91 ReferenceTypeInfo::TypeHandle throwable_class_handle_;
92 };
93
94 class RTPVisitor;
95
Mads Ager16e52892017-07-14 13:11:37 +020096 static ReferenceTypeInfo MergeTypes(const ReferenceTypeInfo& a,
97 const ReferenceTypeInfo& b,
98 HandleCache* handle_cache)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -070099 REQUIRES_SHARED(Locks::mutator_lock_);
Calin Juravleacf735c2015-02-12 15:25:22 +0000100
Calin Juravlecdfed3d2015-10-26 14:05:01 +0000101 void ValidateTypes();
102
Vladimir Marko8d6768d2017-03-14 10:13:21 +0000103 Handle<mirror::ClassLoader> class_loader_;
104
Vladimir Marko456307a2016-04-19 14:12:13 +0000105 // Note: hint_dex_cache_ is usually, but not necessarily, the dex cache associated with
106 // graph_->GetDexFile(). Since we may look up also in other dex files, it's used only
107 // as a hint, to reduce the number of calls to the costly ClassLinker::FindDexCache().
108 Handle<mirror::DexCache> hint_dex_cache_;
Vladimir Marko7d1fbf32016-01-26 15:01:12 +0000109 HandleCache handle_cache_;
Calin Juravle10e244f2015-01-26 18:54:32 +0000110
Nicolas Geoffrayd9994f02016-02-11 17:35:55 +0000111 // Whether this reference type propagation is the first run we are doing.
112 const bool is_first_run_;
Calin Juravle2e768302015-07-28 14:41:11 +0000113
Aart Bik8b3f9b22016-04-06 11:22:12 -0700114 friend class ReferenceTypePropagationTest;
115
Calin Juravle10e244f2015-01-26 18:54:32 +0000116 DISALLOW_COPY_AND_ASSIGN(ReferenceTypePropagation);
117};
118
119} // namespace art
120
121#endif // ART_COMPILER_OPTIMIZING_REFERENCE_TYPE_PROPAGATION_H_