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

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

Issue 834373003: BlinkGCPlugin: require GC mixin instances to declare local trace(). (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Add missing 'override' annotations; sync heap/stubs.h with upstream defs Created 5 years, 11 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 is_stack_allocated_(kNotComputed), 18 is_stack_allocated_(kNotComputed),
19 is_non_newable_(kNotComputed), 19 is_non_newable_(kNotComputed),
20 is_only_placement_newable_(kNotComputed), 20 is_only_placement_newable_(kNotComputed),
21 does_need_finalization_(kNotComputed), 21 does_need_finalization_(kNotComputed),
22 has_gc_mixin_methods_(kNotComputed),
23 is_declaring_local_trace_(kNotComputed),
22 determined_trace_methods_(false), 24 determined_trace_methods_(false),
23 trace_method_(0), 25 trace_method_(0),
24 trace_dispatch_method_(0), 26 trace_dispatch_method_(0),
25 finalize_dispatch_method_(0), 27 finalize_dispatch_method_(0),
26 is_gc_derived_(false) {} 28 is_gc_derived_(false) {}
27 29
28 RecordInfo::~RecordInfo() { 30 RecordInfo::~RecordInfo() {
29 delete fields_; 31 delete fields_;
30 delete bases_; 32 delete bases_;
31 } 33 }
(...skipping 270 matching lines...) Expand 10 before | Expand all | Expand 10 after
302 CXXMethodDecl* RecordInfo::InheritsNonVirtualTrace() { 304 CXXMethodDecl* RecordInfo::InheritsNonVirtualTrace() {
303 if (CXXMethodDecl* trace = GetTraceMethod()) 305 if (CXXMethodDecl* trace = GetTraceMethod())
304 return trace->isVirtual() ? 0 : trace; 306 return trace->isVirtual() ? 0 : trace;
305 for (Bases::iterator it = GetBases().begin(); it != GetBases().end(); ++it) { 307 for (Bases::iterator it = GetBases().begin(); it != GetBases().end(); ++it) {
306 if (CXXMethodDecl* trace = it->second.info()->InheritsNonVirtualTrace()) 308 if (CXXMethodDecl* trace = it->second.info()->InheritsNonVirtualTrace())
307 return trace; 309 return trace;
308 } 310 }
309 return 0; 311 return 0;
310 } 312 }
311 313
314 bool RecordInfo::DeclaresGCMixinMethods() {
315 DetermineTracingMethods();
316 return has_gc_mixin_methods_;
317 }
318
319 bool RecordInfo::DeclaresLocalTraceMethod() {
320 if (is_declaring_local_trace_ != kNotComputed)
321 return is_declaring_local_trace_;
322 DetermineTracingMethods();
323 is_declaring_local_trace_ = trace_method_ ? kTrue : kFalse;
324 if (is_declaring_local_trace_) {
325 for (auto it = record_->method_begin();
326 it != record_->method_end(); ++it) {
327 if (*it == trace_method_) {
328 is_declaring_local_trace_ = kTrue;
329 break;
330 }
331 }
332 }
333 return is_declaring_local_trace_;
334 }
335
336 bool RecordInfo::IsGCMixinInstance() {
337 assert(IsGCDerived());
338 if (record_->isAbstract())
339 return false;
340
341 assert(!IsGCMixin());
342
343 // true iff the class derives from GCMixin and
344 // one or more other GC base classes.
345 bool seen_gc_mixin = false;
346 bool seen_gc_derived = false;
347 for (const auto& gc_base : gc_base_names_) {
348 if (Config::IsGCMixinBase(gc_base))
349 seen_gc_mixin = true;
350 else if (Config::IsGCBase(gc_base))
351 seen_gc_derived = true;
352 }
353 return seen_gc_derived && seen_gc_mixin;
354 }
355
312 // A (non-virtual) class is considered abstract in Blink if it has 356 // A (non-virtual) class is considered abstract in Blink if it has
313 // no public constructors and no create methods. 357 // no public constructors and no create methods.
314 bool RecordInfo::IsConsideredAbstract() { 358 bool RecordInfo::IsConsideredAbstract() {
315 for (CXXRecordDecl::ctor_iterator it = record_->ctor_begin(); 359 for (CXXRecordDecl::ctor_iterator it = record_->ctor_begin();
316 it != record_->ctor_end(); 360 it != record_->ctor_end();
317 ++it) { 361 ++it) {
318 if (!it->isCopyOrMoveConstructor() && it->getAccess() == AS_public) 362 if (!it->isCopyOrMoveConstructor() && it->getAccess() == AS_public)
319 return false; 363 return false;
320 } 364 }
321 for (CXXRecordDecl::method_iterator it = record_->method_begin(); 365 for (CXXRecordDecl::method_iterator it = record_->method_begin();
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
378 422
379 void RecordInfo::DetermineTracingMethods() { 423 void RecordInfo::DetermineTracingMethods() {
380 if (determined_trace_methods_) 424 if (determined_trace_methods_)
381 return; 425 return;
382 determined_trace_methods_ = true; 426 determined_trace_methods_ = true;
383 if (Config::IsGCBase(name_)) 427 if (Config::IsGCBase(name_))
384 return; 428 return;
385 CXXMethodDecl* trace = 0; 429 CXXMethodDecl* trace = 0;
386 CXXMethodDecl* traceAfterDispatch = 0; 430 CXXMethodDecl* traceAfterDispatch = 0;
387 bool isTraceAfterDispatch; 431 bool isTraceAfterDispatch;
432 bool hasAdjustAndMark = false;
433 bool hasIsHeapObjectAlive = false;
388 for (CXXRecordDecl::method_iterator it = record_->method_begin(); 434 for (CXXRecordDecl::method_iterator it = record_->method_begin();
389 it != record_->method_end(); 435 it != record_->method_end();
390 ++it) { 436 ++it) {
391 if (Config::IsTraceMethod(*it, &isTraceAfterDispatch)) { 437 if (Config::IsTraceMethod(*it, &isTraceAfterDispatch)) {
392 if (isTraceAfterDispatch) { 438 if (isTraceAfterDispatch) {
393 traceAfterDispatch = *it; 439 traceAfterDispatch = *it;
394 } else { 440 } else {
395 trace = *it; 441 trace = *it;
396 } 442 }
397 } else if (it->getNameAsString() == kFinalizeName) { 443 } else if (it->getNameAsString() == kFinalizeName) {
398 finalize_dispatch_method_ = *it; 444 finalize_dispatch_method_ = *it;
445 } else if (it->getNameAsString() == kAdjustAndMarkName) {
446 hasAdjustAndMark = true;
447 } else if (it->getNameAsString() == kIsHeapObjectAliveName) {
448 hasIsHeapObjectAlive = true;
399 } 449 }
400 } 450 }
451 // Record if class defines the two GCMixin methods.
452 has_gc_mixin_methods_ =
453 hasAdjustAndMark && hasIsHeapObjectAlive ? kTrue : kFalse;
401 if (traceAfterDispatch) { 454 if (traceAfterDispatch) {
402 trace_method_ = traceAfterDispatch; 455 trace_method_ = traceAfterDispatch;
403 trace_dispatch_method_ = trace; 456 trace_dispatch_method_ = trace;
404 } else { 457 } else {
405 // TODO: Can we never have a dispatch method called trace without the same 458 // TODO: Can we never have a dispatch method called trace without the same
406 // class defining a traceAfterDispatch method? 459 // class defining a traceAfterDispatch method?
407 trace_method_ = trace; 460 trace_method_ = trace;
408 trace_dispatch_method_ = 0; 461 trace_dispatch_method_ = 0;
409 } 462 }
410 if (trace_dispatch_method_ && finalize_dispatch_method_) 463 if (trace_dispatch_method_ && finalize_dispatch_method_)
(...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after
572 edge->members().push_back(member); 625 edge->members().push_back(member);
573 } 626 }
574 // TODO: Handle the case where we fail to create an edge (eg, if the 627 // TODO: Handle the case where we fail to create an edge (eg, if the
575 // argument is a primitive type or just not fully known yet). 628 // argument is a primitive type or just not fully known yet).
576 } 629 }
577 return edge; 630 return edge;
578 } 631 }
579 632
580 return new Value(info); 633 return new Value(info);
581 } 634 }
OLDNEW
« no previous file with comments | « tools/clang/blink_gc_plugin/RecordInfo.h ('k') | tools/clang/blink_gc_plugin/tests/class_multiple_trace_bases.txt » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698