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

Side by Side Diff: tools/clang/blink_gc_plugin/RecordInfo.cpp

Issue 1645763004: blink_gc_plugin: Make RecordInfo::Get{Fields,Bases} return deterministic order (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 10 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
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 using namespace clang; 8 using namespace clang;
9 using std::string; 9 using std::string;
10 10
11 RecordInfo::RecordInfo(CXXRecordDecl* record, RecordCache* cache) 11 RecordInfo::RecordInfo(CXXRecordDecl* record, RecordCache* cache)
12 : cache_(cache), 12 : cache_(cache),
13 record_(record), 13 record_(record),
14 name_(record->getName()), 14 name_(record->getName()),
15 fields_need_tracing_(TracingStatus::Unknown()), 15 fields_need_tracing_(TracingStatus::Unknown()),
16 bases_(0), 16 bases_(0),
17 fields_(0), 17 fields_(0),
18 field_map_(0),
18 is_stack_allocated_(kNotComputed), 19 is_stack_allocated_(kNotComputed),
19 is_non_newable_(kNotComputed), 20 is_non_newable_(kNotComputed),
20 is_only_placement_newable_(kNotComputed), 21 is_only_placement_newable_(kNotComputed),
21 does_need_finalization_(kNotComputed), 22 does_need_finalization_(kNotComputed),
22 has_gc_mixin_methods_(kNotComputed), 23 has_gc_mixin_methods_(kNotComputed),
23 is_declaring_local_trace_(kNotComputed), 24 is_declaring_local_trace_(kNotComputed),
24 is_eagerly_finalized_(kNotComputed), 25 is_eagerly_finalized_(kNotComputed),
25 determined_trace_methods_(false), 26 determined_trace_methods_(false),
26 trace_method_(0), 27 trace_method_(0),
27 trace_dispatch_method_(0), 28 trace_dispatch_method_(0),
28 finalize_dispatch_method_(0), 29 finalize_dispatch_method_(0),
29 is_gc_derived_(false) {} 30 is_gc_derived_(false) {}
30 31
31 RecordInfo::~RecordInfo() { 32 RecordInfo::~RecordInfo() {
32 delete fields_; 33 delete fields_;
34 delete field_map_;
33 delete bases_; 35 delete bases_;
34 } 36 }
35 37
36 // Get |count| number of template arguments. Returns false if there 38 // Get |count| number of template arguments. Returns false if there
37 // are fewer than |count| arguments or any of the arguments are not 39 // are fewer than |count| arguments or any of the arguments are not
38 // of a valid Type structure. If |count| is non-positive, all 40 // of a valid Type structure. If |count| is non-positive, all
39 // arguments are collected. 41 // arguments are collected.
40 bool RecordInfo::GetTemplateArgs(size_t count, TemplateArgs* output_args) { 42 bool RecordInfo::GetTemplateArgs(size_t count, TemplateArgs* output_args) {
41 ClassTemplateSpecializationDecl* tmpl = 43 ClassTemplateSpecializationDecl* tmpl =
42 dyn_cast<ClassTemplateSpecializationDecl>(record_); 44 dyn_cast<ClassTemplateSpecializationDecl>(record_);
(...skipping 269 matching lines...) Expand 10 before | Expand all | Expand 10 after
312 return trace_dispatch_method_; 314 return trace_dispatch_method_;
313 } 315 }
314 316
315 CXXMethodDecl* RecordInfo::GetFinalizeDispatchMethod() { 317 CXXMethodDecl* RecordInfo::GetFinalizeDispatchMethod() {
316 DetermineTracingMethods(); 318 DetermineTracingMethods();
317 return finalize_dispatch_method_; 319 return finalize_dispatch_method_;
318 } 320 }
319 321
320 RecordInfo::Bases& RecordInfo::GetBases() { 322 RecordInfo::Bases& RecordInfo::GetBases() {
321 if (!bases_) 323 if (!bases_)
322 bases_ = CollectBases(); 324 CollectBases();
323 return *bases_; 325 return *bases_;
324 } 326 }
325 327
326 bool RecordInfo::InheritsTrace() { 328 bool RecordInfo::InheritsTrace() {
327 if (GetTraceMethod()) 329 if (GetTraceMethod())
328 return true; 330 return true;
329 for (Bases::iterator it = GetBases().begin(); it != GetBases().end(); ++it) { 331 for (Bases::iterator it = GetBases().begin(); it != GetBases().end(); ++it) {
330 if (it->second.info()->InheritsTrace()) 332 if (it->second.info()->InheritsTrace())
331 return true; 333 return true;
332 } 334 }
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
376 } 378 }
377 for (CXXRecordDecl::method_iterator it = record_->method_begin(); 379 for (CXXRecordDecl::method_iterator it = record_->method_begin();
378 it != record_->method_end(); 380 it != record_->method_end();
379 ++it) { 381 ++it) {
380 if (it->getNameAsString() == kCreateName) 382 if (it->getNameAsString() == kCreateName)
381 return false; 383 return false;
382 } 384 }
383 return true; 385 return true;
384 } 386 }
385 387
386 RecordInfo::Bases* RecordInfo::CollectBases() { 388 void RecordInfo::CollectBases() {
387 // Compute the collection locally to avoid inconsistent states. 389 // Compute the collection locally to avoid inconsistent states.
388 Bases* bases = new Bases; 390 assert(!bases_);
391 bases_ = new Bases;
389 if (!record_->hasDefinition()) 392 if (!record_->hasDefinition())
390 return bases; 393 return;
391 for (CXXRecordDecl::base_class_iterator it = record_->bases_begin(); 394 for (CXXRecordDecl::base_class_iterator it = record_->bases_begin();
392 it != record_->bases_end(); 395 it != record_->bases_end();
393 ++it) { 396 ++it) {
394 const CXXBaseSpecifier& spec = *it; 397 const CXXBaseSpecifier& spec = *it;
395 RecordInfo* info = cache_->Lookup(spec.getType()); 398 RecordInfo* info = cache_->Lookup(spec.getType());
396 if (!info) 399 if (!info)
397 continue; 400 continue;
398 CXXRecordDecl* base = info->record(); 401 CXXRecordDecl* base = info->record();
399 TracingStatus status = info->InheritsTrace() 402 TracingStatus status = info->InheritsTrace()
400 ? TracingStatus::Needed() 403 ? TracingStatus::Needed()
401 : TracingStatus::Unneeded(); 404 : TracingStatus::Unneeded();
402 bases->insert(std::make_pair(base, BasePoint(spec, info, status))); 405 bases_->push_back(std::make_pair(base, BasePoint(spec, info, status)));
403 } 406 }
404 return bases;
405 } 407 }
406 408
407 RecordInfo::Fields& RecordInfo::GetFields() { 409 RecordInfo::Fields& RecordInfo::GetFields() {
408 if (!fields_) 410 if (!fields_) {
409 fields_ = CollectFields(); 411 assert(!field_map_);
412 CollectFields();
413 }
410 return *fields_; 414 return *fields_;
411 } 415 }
412 416
413 RecordInfo::Fields* RecordInfo::CollectFields() { 417 bool RecordInfo::HasField(clang::FieldDecl* field) {
418 GetFields();
419 assert(field_map_);
420 return field_map_->count(field);
421 }
422
423 RecordInfo::Field& RecordInfo::GetField(clang::FieldDecl* field) {
424 assert(HasField(field));
425 return fields_->at((*field_map_)[field]);
426 }
427
428 void RecordInfo::CollectFields() {
414 // Compute the collection locally to avoid inconsistent states. 429 // Compute the collection locally to avoid inconsistent states.
415 Fields* fields = new Fields; 430 assert(!fields_);
431 fields_ = new Fields;
432 field_map_ = new std::map<clang::FieldDecl*, size_t>;
433
416 if (!record_->hasDefinition()) 434 if (!record_->hasDefinition())
417 return fields; 435 return;
436
418 TracingStatus fields_status = TracingStatus::Unneeded(); 437 TracingStatus fields_status = TracingStatus::Unneeded();
419 for (RecordDecl::field_iterator it = record_->field_begin(); 438 for (RecordDecl::field_iterator it = record_->field_begin();
420 it != record_->field_end(); 439 it != record_->field_end();
421 ++it) { 440 ++it) {
422 FieldDecl* field = *it; 441 FieldDecl* field = *it;
423 // Ignore fields annotated with the GC_PLUGIN_IGNORE macro. 442 // Ignore fields annotated with the GC_PLUGIN_IGNORE macro.
424 if (Config::IsIgnoreAnnotated(field)) 443 if (Config::IsIgnoreAnnotated(field))
425 continue; 444 continue;
426 if (Edge* edge = CreateEdge(field->getType().getTypePtrOrNull())) { 445 if (Edge* edge = CreateEdge(field->getType().getTypePtrOrNull())) {
427 fields_status = fields_status.LUB(edge->NeedsTracing(Edge::kRecursive)); 446 fields_status = fields_status.LUB(edge->NeedsTracing(Edge::kRecursive));
428 fields->insert(std::make_pair(field, FieldPoint(field, edge))); 447 (*field_map_)[field] = fields_->size();
448 fields_->push_back(std::make_pair(field, FieldPoint(field, edge)));
429 } 449 }
430 } 450 }
431 fields_need_tracing_ = fields_status; 451 fields_need_tracing_ = fields_status;
432 return fields;
433 } 452 }
434 453
435 void RecordInfo::DetermineTracingMethods() { 454 void RecordInfo::DetermineTracingMethods() {
436 if (determined_trace_methods_) 455 if (determined_trace_methods_)
437 return; 456 return;
438 determined_trace_methods_ = true; 457 determined_trace_methods_ = true;
439 if (Config::IsGCBase(name_)) 458 if (Config::IsGCBase(name_))
440 return; 459 return;
441 CXXMethodDecl* trace = nullptr; 460 CXXMethodDecl* trace = nullptr;
442 CXXMethodDecl* trace_impl = nullptr; 461 CXXMethodDecl* trace_impl = nullptr;
(...skipping 211 matching lines...) Expand 10 before | Expand all | Expand 10 after
654 edge->members().push_back(member); 673 edge->members().push_back(member);
655 } 674 }
656 // TODO: Handle the case where we fail to create an edge (eg, if the 675 // TODO: Handle the case where we fail to create an edge (eg, if the
657 // argument is a primitive type or just not fully known yet). 676 // argument is a primitive type or just not fully known yet).
658 } 677 }
659 return edge; 678 return edge;
660 } 679 }
661 680
662 return new Value(info); 681 return new Value(info);
663 } 682 }
OLDNEW
« tools/clang/blink_gc_plugin/RecordInfo.h ('K') | « tools/clang/blink_gc_plugin/RecordInfo.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698