Commit f0e68a48 authored by yutak's avatar yutak Committed by Commit bot

GCPlugin: Recognize templated registerWeakMembers() call.

After the inlined trace transition, the callee part of registerWeakMembers()
call can be of type CXXDependentScopeMemberExpr instead of UnresolvedMemberExpr.
The plugin should be aware of this case.

BUG=462511
R=kouhei@chromium.org
CC=zerny@chromium.org, oilpan-reviews@chromium.org

Review URL: https://codereview.chromium.org/975683003

Cr-Commit-Position: refs/heads/master@{#319024}
parent 8e40655a
...@@ -388,17 +388,8 @@ class CheckTraceVisitor : public RecursiveASTVisitor<CheckTraceVisitor> { ...@@ -388,17 +388,8 @@ class CheckTraceVisitor : public RecursiveASTVisitor<CheckTraceVisitor> {
if (CheckTraceBaseCall(call)) if (CheckTraceBaseCall(call))
return true; return true;
// If we find a call to registerWeakMembers which is unresolved we if (expr->getMemberName().getAsString() == kRegisterWeakMembersName)
// unsoundly consider all weak members as traced. MarkAllWeakMembersTraced();
// TODO: Find out how to validate weak member tracing for unresolved call.
if (expr->getMemberName().getAsString() == kRegisterWeakMembersName) {
for (RecordInfo::Fields::iterator it = info_->GetFields().begin();
it != info_->GetFields().end();
++it) {
if (it->second.edge()->IsWeakMember())
it->second.MarkTraced();
}
}
QualType base = expr->getBaseType(); QualType base = expr->getBaseType();
if (!base->isPointerType()) if (!base->isPointerType())
...@@ -454,18 +445,23 @@ class CheckTraceVisitor : public RecursiveASTVisitor<CheckTraceVisitor> { ...@@ -454,18 +445,23 @@ class CheckTraceVisitor : public RecursiveASTVisitor<CheckTraceVisitor> {
CXXDependentScopeMemberExpr* expr) { CXXDependentScopeMemberExpr* expr) {
string fn_name = expr->getMember().getAsString(); string fn_name = expr->getMember().getAsString();
// Check for VisitorDispatcher::trace(field) // Check for VisitorDispatcher::trace(field) and
// VisitorDispatcher::registerWeakMembers.
if (!expr->isImplicitAccess()) { if (!expr->isImplicitAccess()) {
if (clang::DeclRefExpr* base_decl = if (clang::DeclRefExpr* base_decl =
clang::dyn_cast<clang::DeclRefExpr>(expr->getBase())) { clang::dyn_cast<clang::DeclRefExpr>(expr->getBase())) {
if (Config::IsVisitorDispatcherType(base_decl->getType()) && if (Config::IsVisitorDispatcherType(base_decl->getType())) {
call->getNumArgs() == 1 && fn_name == kTraceName) { if (call->getNumArgs() == 1 && fn_name == kTraceName) {
FindFieldVisitor finder; FindFieldVisitor finder;
finder.TraverseStmt(call->getArg(0)); finder.TraverseStmt(call->getArg(0));
if (finder.field()) if (finder.field())
FoundField(finder.field()); FoundField(finder.field());
return; return;
} else if (call->getNumArgs() == 1 &&
fn_name == kRegisterWeakMembersName) {
MarkAllWeakMembersTraced();
}
} }
} }
} }
...@@ -696,6 +692,16 @@ class CheckTraceVisitor : public RecursiveASTVisitor<CheckTraceVisitor> { ...@@ -696,6 +692,16 @@ class CheckTraceVisitor : public RecursiveASTVisitor<CheckTraceVisitor> {
} }
} }
void MarkAllWeakMembersTraced() {
// If we find a call to registerWeakMembers which is unresolved we
// unsoundly consider all weak members as traced.
// TODO: Find out how to validate weak member tracing for unresolved call.
for (auto& field : info_->GetFields()) {
if (field.second.edge()->IsWeakMember())
field.second.MarkTraced();
}
}
CXXMethodDecl* trace_; CXXMethodDecl* trace_;
RecordInfo* info_; RecordInfo* info_;
RecordCache* cache_; RecordCache* cache_;
......
...@@ -221,6 +221,9 @@ class InlinedGlobalMarkingVisitor ...@@ -221,6 +221,9 @@ class InlinedGlobalMarkingVisitor
: public VisitorHelper<InlinedGlobalMarkingVisitor> { : public VisitorHelper<InlinedGlobalMarkingVisitor> {
public: public:
InlinedGlobalMarkingVisitor* operator->() { return this; } InlinedGlobalMarkingVisitor* operator->() { return this; }
template<typename T, void (T::*method)(Visitor*)>
void registerWeakMembers(const T* obj);
}; };
class GarbageCollectedMixin { class GarbageCollectedMixin {
......
// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "register_weak_members_template.h"
// Nothing to define here.
// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef REGISTER_WEAK_MEMBERS_TEMPLATE_H_
#define REGISTER_WEAK_MEMBERS_TEMPLATE_H_
#include "heap/stubs.h"
namespace blink {
class X : public GarbageCollected<X> {
public:
void trace(Visitor* visitor) { traceImpl(visitor); }
void trace(InlinedGlobalMarkingVisitor visitor) { traceImpl(visitor); }
private:
template <typename VisitorDispatcher>
void traceImpl(VisitorDispatcher visitor) {}
};
class HasUntracedWeakMembers : public GarbageCollected<HasUntracedWeakMembers> {
public:
void trace(Visitor* visitor) { traceImpl(visitor); }
void trace(InlinedGlobalMarkingVisitor visitor) { traceImpl(visitor); }
// Don't have to be defined for the purpose of this test.
void clearWeakMembers(Visitor* visitor);
private:
template <typename VisitorDispatcher>
void traceImpl(VisitorDispatcher visitor) {
visitor->template registerWeakMembers<
HasUntracedWeakMembers,
&HasUntracedWeakMembers::clearWeakMembers>(this);
}
WeakMember<X> x_;
};
}
#endif // REGISTER_WEAK_MEMBERS_TEMPLATE_H_
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment