OLD | NEW |
1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
62 | 62 |
63 return false; | 63 return false; |
64 } | 64 } |
65 | 65 |
66 | 66 |
67 static bool InV8Namespace(const clang::NamedDecl* decl) { | 67 static bool InV8Namespace(const clang::NamedDecl* decl) { |
68 return decl->getQualifiedNameAsString().compare(0, 4, "v8::") == 0; | 68 return decl->getQualifiedNameAsString().compare(0, 4, "v8::") == 0; |
69 } | 69 } |
70 | 70 |
71 | 71 |
| 72 static std::string EXTERNAL("EXTERNAL"); |
| 73 static std::string STATE_TAG("enum v8::internal::StateTag"); |
| 74 |
| 75 static bool IsExternalVMState(const clang::ValueDecl* var) { |
| 76 const clang::EnumConstantDecl* enum_constant = |
| 77 dyn_cast<clang::EnumConstantDecl>(var); |
| 78 if (enum_constant != NULL && enum_constant->getNameAsString() == EXTERNAL) { |
| 79 clang::QualType type = enum_constant->getType(); |
| 80 return (type.getAsString() == STATE_TAG); |
| 81 } |
| 82 |
| 83 return false; |
| 84 } |
| 85 |
| 86 |
72 struct Resolver { | 87 struct Resolver { |
73 explicit Resolver(clang::ASTContext& ctx) | 88 explicit Resolver(clang::ASTContext& ctx) |
74 : ctx_(ctx), decl_ctx_(ctx.getTranslationUnitDecl()) { | 89 : ctx_(ctx), decl_ctx_(ctx.getTranslationUnitDecl()) { |
75 } | 90 } |
76 | 91 |
77 Resolver(clang::ASTContext& ctx, clang::DeclContext* decl_ctx) | 92 Resolver(clang::ASTContext& ctx, clang::DeclContext* decl_ctx) |
78 : ctx_(ctx), decl_ctx_(decl_ctx) { | 93 : ctx_(ctx), decl_ctx_(decl_ctx) { |
79 } | 94 } |
80 | 95 |
81 clang::DeclarationName ResolveName(const char* n) { | 96 clang::DeclarationName ResolveName(const char* n) { |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
114 public: | 129 public: |
115 explicit CalleesPrinter(clang::MangleContext* ctx) : ctx_(ctx) { | 130 explicit CalleesPrinter(clang::MangleContext* ctx) : ctx_(ctx) { |
116 } | 131 } |
117 | 132 |
118 virtual bool VisitCallExpr(clang::CallExpr* expr) { | 133 virtual bool VisitCallExpr(clang::CallExpr* expr) { |
119 const clang::FunctionDecl* callee = expr->getDirectCallee(); | 134 const clang::FunctionDecl* callee = expr->getDirectCallee(); |
120 if (callee != NULL) AnalyzeFunction(callee); | 135 if (callee != NULL) AnalyzeFunction(callee); |
121 return true; | 136 return true; |
122 } | 137 } |
123 | 138 |
| 139 virtual bool VisitDeclRefExpr(clang::DeclRefExpr* expr) { |
| 140 // If function mentions EXTERNAL VMState add artificial garbage collection |
| 141 // mark. |
| 142 if (IsExternalVMState(expr->getDecl())) AddCallee("CollectGarbage"); |
| 143 return true; |
| 144 } |
| 145 |
124 void AnalyzeFunction(const clang::FunctionDecl* f) { | 146 void AnalyzeFunction(const clang::FunctionDecl* f) { |
125 MangledName name; | 147 MangledName name; |
126 if (InV8Namespace(f) && GetMangledName(ctx_, f, &name)) { | 148 if (InV8Namespace(f) && GetMangledName(ctx_, f, &name)) { |
127 AddCallee(name); | 149 AddCallee(name); |
128 | 150 |
129 const clang::FunctionDecl* body = NULL; | 151 const clang::FunctionDecl* body = NULL; |
130 if (f->hasBody(body) && !Analyzed(name)) { | 152 if (f->hasBody(body) && !Analyzed(name)) { |
131 EnterScope(name); | 153 EnterScope(name); |
132 TraverseStmt(body->getBody()); | 154 TraverseStmt(body->getBody()); |
133 LeaveScope(); | 155 LeaveScope(); |
(...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
271 static ExprEffect RawUse() { return ExprEffect(kRawUse, NULL); } | 293 static ExprEffect RawUse() { return ExprEffect(kRawUse, NULL); } |
272 | 294 |
273 static ExprEffect Merge(ExprEffect a, ExprEffect b); | 295 static ExprEffect Merge(ExprEffect a, ExprEffect b); |
274 static ExprEffect MergeSeq(ExprEffect a, ExprEffect b); | 296 static ExprEffect MergeSeq(ExprEffect a, ExprEffect b); |
275 ExprEffect Define(const std::string& name); | 297 ExprEffect Define(const std::string& name); |
276 | 298 |
277 Environment* env() { | 299 Environment* env() { |
278 return reinterpret_cast<Environment*>(effect_ & ~kAllEffects); | 300 return reinterpret_cast<Environment*>(effect_ & ~kAllEffects); |
279 } | 301 } |
280 | 302 |
| 303 static ExprEffect GC() { |
| 304 return ExprEffect(kCausesGC, NULL); |
| 305 } |
| 306 |
281 private: | 307 private: |
282 ExprEffect(int effect, Environment* env) | 308 ExprEffect(int effect, Environment* env) |
283 : effect_((effect & kAllEffects) | | 309 : effect_((effect & kAllEffects) | |
284 reinterpret_cast<intptr_t>(env)) { } | 310 reinterpret_cast<intptr_t>(env)) { } |
285 | 311 |
286 intptr_t effect_; | 312 intptr_t effect_; |
287 }; | 313 }; |
288 | 314 |
289 | 315 |
290 const std::string BAD_EXPR_MSG("Possible problem with evaluation order."); | 316 const std::string BAD_EXPR_MSG("Possible problem with evaluation order."); |
(...skipping 492 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
783 ReportUnsafe(parent, DEAD_VAR_MSG); | 809 ReportUnsafe(parent, DEAD_VAR_MSG); |
784 } | 810 } |
785 return ExprEffect::RawUse(); | 811 return ExprEffect::RawUse(); |
786 } | 812 } |
787 return ExprEffect::None(); | 813 return ExprEffect::None(); |
788 } | 814 } |
789 | 815 |
790 ExprEffect Use(const clang::Expr* parent, | 816 ExprEffect Use(const clang::Expr* parent, |
791 const clang::ValueDecl* var, | 817 const clang::ValueDecl* var, |
792 const Environment& env) { | 818 const Environment& env) { |
| 819 if (IsExternalVMState(var)) { |
| 820 return ExprEffect::GC(); |
| 821 } |
793 return Use(parent, var->getType(), var->getNameAsString(), env); | 822 return Use(parent, var->getType(), var->getNameAsString(), env); |
794 } | 823 } |
795 | 824 |
796 | 825 |
797 template<typename ExprType> | 826 template<typename ExprType> |
798 ExprEffect VisitArguments(ExprType* call, const Environment& env) { | 827 ExprEffect VisitArguments(ExprType* call, const Environment& env) { |
799 CallProps props; | 828 CallProps props; |
800 VisitArguments<>(call, &props, env); | 829 VisitArguments<>(call, &props, env); |
801 if (!props.IsSafe()) ReportUnsafe(call, BAD_EXPR_MSG); | 830 if (!props.IsSafe()) ReportUnsafe(call, BAD_EXPR_MSG); |
802 return props.ComputeCumulativeEffect(IsRawPointerType(call->getType())); | 831 return props.ComputeCumulativeEffect(IsRawPointerType(call->getType())); |
(...skipping 449 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1252 | 1281 |
1253 | 1282 |
1254 } | 1283 } |
1255 | 1284 |
1256 static clang::FrontendPluginRegistry::Add<Action<ProblemsFinder> > | 1285 static clang::FrontendPluginRegistry::Add<Action<ProblemsFinder> > |
1257 FindProblems("find-problems", "Find GC-unsafe places."); | 1286 FindProblems("find-problems", "Find GC-unsafe places."); |
1258 | 1287 |
1259 static clang::FrontendPluginRegistry::Add< | 1288 static clang::FrontendPluginRegistry::Add< |
1260 Action<FunctionDeclarationFinder> > | 1289 Action<FunctionDeclarationFinder> > |
1261 DumpCallees("dump-callees", "Dump callees for each function."); | 1290 DumpCallees("dump-callees", "Dump callees for each function."); |
OLD | NEW |