OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "Config.h" | 5 #include "Config.h" |
6 #include "RecordInfo.h" | 6 #include "RecordInfo.h" |
7 | 7 |
8 #include "clang/AST/Attr.h" | |
9 | |
10 using namespace clang; | 8 using namespace clang; |
11 using std::string; | 9 using std::string; |
12 | 10 |
13 RecordInfo::RecordInfo(CXXRecordDecl* record, RecordCache* cache) | 11 RecordInfo::RecordInfo(CXXRecordDecl* record, RecordCache* cache) |
14 : cache_(cache), | 12 : cache_(cache), |
15 record_(record), | 13 record_(record), |
16 name_(record->getName()), | 14 name_(record->getName()), |
17 fields_need_tracing_(TracingStatus::Unknown()), | 15 fields_need_tracing_(TracingStatus::Unknown()), |
18 bases_(0), | 16 bases_(0), |
19 fields_(0), | 17 fields_(0), |
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
129 return false; | 127 return false; |
130 // This is a mixin if there are no other paths to GC bases. | 128 // This is a mixin if there are no other paths to GC bases. |
131 return ++it == base_paths_->end(); | 129 return ++it == base_paths_->end(); |
132 } | 130 } |
133 | 131 |
134 // Test if a record is allocated on the managed heap. | 132 // Test if a record is allocated on the managed heap. |
135 bool RecordInfo::IsGCAllocated() { | 133 bool RecordInfo::IsGCAllocated() { |
136 return IsGCDerived() || IsHeapAllocatedCollection(); | 134 return IsGCDerived() || IsHeapAllocatedCollection(); |
137 } | 135 } |
138 | 136 |
139 static bool IsAnnotated(Decl* decl, const string& anno) { | |
140 AnnotateAttr* attr = decl->getAttr<AnnotateAttr>(); | |
141 return attr && (attr->getAnnotation() == anno); | |
142 } | |
143 | |
144 RecordInfo* RecordCache::Lookup(CXXRecordDecl* record) { | 137 RecordInfo* RecordCache::Lookup(CXXRecordDecl* record) { |
145 // Ignore classes annotated with the GC_PLUGIN_IGNORE macro. | 138 // Ignore classes annotated with the GC_PLUGIN_IGNORE macro. |
146 if (!record || IsAnnotated(record, "blink_gc_plugin_ignore")) | 139 if (!record || Config::IsIgnoreAnnotated(record)) |
147 return 0; | 140 return 0; |
148 Cache::iterator it = cache_.find(record); | 141 Cache::iterator it = cache_.find(record); |
149 if (it != cache_.end()) | 142 if (it != cache_.end()) |
150 return &it->second; | 143 return &it->second; |
151 return &cache_.insert(std::make_pair(record, RecordInfo(record, this))) | 144 return &cache_.insert(std::make_pair(record, RecordInfo(record, this))) |
152 .first->second; | 145 .first->second; |
153 } | 146 } |
154 | 147 |
155 bool RecordInfo::IsStackAllocated() { | 148 bool RecordInfo::IsStackAllocated() { |
156 if (is_stack_allocated_ == kNotComputed) { | 149 if (is_stack_allocated_ == kNotComputed) { |
157 is_stack_allocated_ = kFalse; | 150 is_stack_allocated_ = kFalse; |
158 for (Bases::iterator it = GetBases().begin(); | 151 for (Bases::iterator it = GetBases().begin(); |
159 it != GetBases().end(); | 152 it != GetBases().end(); |
160 ++it) { | 153 ++it) { |
161 if (it->second.info()->IsStackAllocated()) { | 154 if (it->second.info()->IsStackAllocated()) { |
162 is_stack_allocated_ = kTrue; | 155 is_stack_allocated_ = kTrue; |
163 break; | 156 return is_stack_allocated_; |
164 } | 157 } |
165 } | 158 } |
166 for (CXXRecordDecl::method_iterator it = record_->method_begin(); | 159 for (CXXRecordDecl::method_iterator it = record_->method_begin(); |
167 it != record_->method_end(); | 160 it != record_->method_end(); |
168 ++it) { | 161 ++it) { |
169 if (it->getNameAsString() == kNewOperatorName) { | 162 if (it->getNameAsString() == kNewOperatorName && |
170 if (it->isDeleted() && IsAnnotated(*it, "blink_stack_allocated")) { | 163 it->isDeleted() && |
171 is_stack_allocated_ = kTrue; | 164 Config::IsStackAnnotated(*it)) { |
172 break; | 165 is_stack_allocated_ = kTrue; |
173 } | 166 return is_stack_allocated_; |
174 } | 167 } |
175 } | 168 } |
176 } | 169 } |
177 return is_stack_allocated_; | 170 return is_stack_allocated_; |
178 } | 171 } |
179 | 172 |
180 // An object requires a tracing method if it has any fields that need tracing. | 173 // An object requires a tracing method if it has any fields that need tracing. |
181 bool RecordInfo::RequiresTraceMethod() { | 174 bool RecordInfo::RequiresTraceMethod() { |
182 if (IsStackAllocated()) | 175 if (IsStackAllocated()) |
183 return false; | 176 return false; |
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
278 // Compute the collection locally to avoid inconsistent states. | 271 // Compute the collection locally to avoid inconsistent states. |
279 Fields* fields = new Fields; | 272 Fields* fields = new Fields; |
280 if (!record_->hasDefinition()) | 273 if (!record_->hasDefinition()) |
281 return fields; | 274 return fields; |
282 TracingStatus fields_status = TracingStatus::Unneeded(); | 275 TracingStatus fields_status = TracingStatus::Unneeded(); |
283 for (RecordDecl::field_iterator it = record_->field_begin(); | 276 for (RecordDecl::field_iterator it = record_->field_begin(); |
284 it != record_->field_end(); | 277 it != record_->field_end(); |
285 ++it) { | 278 ++it) { |
286 FieldDecl* field = *it; | 279 FieldDecl* field = *it; |
287 // Ignore fields annotated with the GC_PLUGIN_IGNORE macro. | 280 // Ignore fields annotated with the GC_PLUGIN_IGNORE macro. |
288 if (IsAnnotated(field, "blink_gc_plugin_ignore")) | 281 if (Config::IsIgnoreAnnotated(field)) |
289 continue; | 282 continue; |
290 if (Edge* edge = CreateEdge(field->getType().getTypePtrOrNull())) { | 283 if (Edge* edge = CreateEdge(field->getType().getTypePtrOrNull())) { |
291 fields->insert(std::make_pair(field, FieldPoint(field, edge))); | 284 fields->insert(std::make_pair(field, FieldPoint(field, edge))); |
292 fields_status = fields_status.LUB(edge->NeedsTracing(Edge::kRecursive)); | 285 fields_status = fields_status.LUB(edge->NeedsTracing(Edge::kRecursive)); |
293 } | 286 } |
294 } | 287 } |
295 fields_need_tracing_ = fields_status; | 288 fields_need_tracing_ = fields_status; |
296 return fields; | 289 return fields; |
297 } | 290 } |
298 | 291 |
(...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
452 // We failed to create an edge so abort the entire edge construction. | 445 // We failed to create an edge so abort the entire edge construction. |
453 delete edge; // Will delete the already allocated members. | 446 delete edge; // Will delete the already allocated members. |
454 return 0; | 447 return 0; |
455 } | 448 } |
456 } | 449 } |
457 return edge; | 450 return edge; |
458 } | 451 } |
459 | 452 |
460 return new Value(info); | 453 return new Value(info); |
461 } | 454 } |
OLD | NEW |