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

Side by Side Diff: tools/gcmole/gcmole.cc

Issue 2694103005: [gcmole] Avoid hardcoded maximum of 256 locals (Closed)
Patch Set: Created 3 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
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 300 matching lines...) Expand 10 before | Expand all | Expand 10 after
311 intptr_t effect_; 311 intptr_t effect_;
312 }; 312 };
313 313
314 314
315 const std::string BAD_EXPR_MSG("Possible problem with evaluation order."); 315 const std::string BAD_EXPR_MSG("Possible problem with evaluation order.");
316 const std::string DEAD_VAR_MSG("Possibly dead variable."); 316 const std::string DEAD_VAR_MSG("Possibly dead variable.");
317 317
318 318
319 class Environment { 319 class Environment {
320 public: 320 public:
321 Environment() { } 321 Environment() = default;
322 322
323 static Environment Unreachable() { 323 static Environment Unreachable() {
324 Environment env; 324 Environment env;
325 env.live_.set(); 325 env.unreachable_ = true;
326 return env; 326 return env;
327 } 327 }
328 328
329 static Environment Merge(const Environment& l, 329 static Environment Merge(const Environment& l,
330 const Environment& r) { 330 const Environment& r) {
331 return Environment(l, r); 331 Environment out(l);
332 out &= r;
333 return out;
332 } 334 }
333 335
334 Environment ApplyEffect(ExprEffect effect) const { 336 Environment ApplyEffect(ExprEffect effect) const {
335 Environment out = effect.hasGC() ? Environment() : Environment(*this); 337 Environment out = effect.hasGC() ? Environment() : Environment(*this);
336 if (effect.env() != NULL) out.live_ |= effect.env()->live_; 338 if (effect.env()) out |= *effect.env();
337 return out; 339 return out;
338 } 340 }
339 341
340 typedef std::map<std::string, int> SymbolTable; 342 typedef std::map<std::string, int> SymbolTable;
341 343
342 bool IsAlive(const std::string& name) const { 344 bool IsAlive(const std::string& name) const {
343 SymbolTable::iterator code = symbol_table_.find(name); 345 SymbolTable::iterator code = symbol_table_.find(name);
344 if (code == symbol_table_.end()) return false; 346 if (code == symbol_table_.end()) return false;
345 return live_[code->second]; 347 return is_live(code->second);
346 } 348 }
347 349
348 bool Equal(const Environment& env) { 350 bool Equal(const Environment& env) {
349 return live_ == env.live_; 351 if (unreachable_) return env.unreachable_;
Michael Achenbach 2017/02/15 15:13:13 So, there's an invariant that if unreachable==true
Clemens Hammacher 2017/02/15 15:19:55 If unreachable==true, then is_live always returns
Vyacheslav Egorov (Google) 2017/02/15 15:48:15 This does not seem correct. We have: env.unreach
Vyacheslav Egorov (Google) 2017/02/15 15:59:37 Clarification: environment where unreachable_ is
352 size_t size = std::max(live_.size(), env.live_.size());
Michael Achenbach 2017/02/15 15:13:13 Maybe return false early if size differs?
Clemens Hammacher 2017/02/15 15:19:54 That would be a stronger check than before. In thi
Michael Starzinger 2017/02/15 15:20:12 Wouldn't that change semantics? If the size is dif
353 for (size_t i = 0; i < size; ++i) {
354 if (is_live(i) != env.is_live(i)) return false;
355 }
356 return true;
350 } 357 }
351 358
352 Environment Define(const std::string& name) const { 359 Environment Define(const std::string& name) const {
353 return Environment(*this, SymbolToCode(name)); 360 return Environment(*this, SymbolToCode(name));
354 } 361 }
355 362
356 void MDefine(const std::string& name) { 363 void MDefine(const std::string& name) { set_live(SymbolToCode(name)); }
357 live_.set(SymbolToCode(name));
358 }
359 364
360 static int SymbolToCode(const std::string& name) { 365 static int SymbolToCode(const std::string& name) {
361 SymbolTable::iterator code = symbol_table_.find(name); 366 SymbolTable::iterator code = symbol_table_.find(name);
362 367
363 if (code == symbol_table_.end()) { 368 if (code == symbol_table_.end()) {
364 int new_code = symbol_table_.size(); 369 int new_code = symbol_table_.size();
365 symbol_table_.insert(std::make_pair(name, new_code)); 370 symbol_table_.insert(std::make_pair(name, new_code));
366 return new_code; 371 return new_code;
367 } 372 }
368 373
369 return code->second; 374 return code->second;
370 } 375 }
371 376
372 static void ClearSymbolTable() { 377 static void ClearSymbolTable() {
373 std::vector<Environment*>::iterator end = envs_.end(); 378 for (Environment* e : envs_) delete e;
374 for (std::vector<Environment*>::iterator i = envs_.begin();
375 i != end;
376 ++i) {
377 delete *i;
378 }
379 envs_.clear(); 379 envs_.clear();
380 symbol_table_.clear(); 380 symbol_table_.clear();
381 } 381 }
382 382
383 void Print() const { 383 void Print() const {
384 bool comma = false; 384 bool comma = false;
385 std::cout << "{"; 385 std::cout << "{";
386 SymbolTable::iterator end = symbol_table_.end(); 386 for (auto& e : symbol_table_) {
387 for (SymbolTable::iterator i = symbol_table_.begin(); 387 if (!is_live(e.second)) continue;
388 i != end; 388 if (comma) std::cout << ", ";
389 ++i) { 389 std::cout << e.first;
390 if (live_[i->second]) { 390 comma = true;
391 if (comma) std::cout << ", ";
392 std::cout << i->first;
393 comma = true;
394 }
395 } 391 }
396 std::cout << "}"; 392 std::cout << "}";
397 } 393 }
398 394
399 static Environment* Allocate(const Environment& env) { 395 static Environment* Allocate(const Environment& env) {
400 Environment* allocated_env = new Environment(env); 396 Environment* allocated_env = new Environment(env);
401 envs_.push_back(allocated_env); 397 envs_.push_back(allocated_env);
402 return allocated_env; 398 return allocated_env;
403 } 399 }
404 400
405 private: 401 private:
406 Environment(const Environment& l, const Environment& r) 402 Environment(const Environment& l, int code)
407 : live_(l.live_ & r.live_) { 403 : live_(l.live_) {
404 set_live(code);
408 } 405 }
409 406
410 Environment(const Environment& l, int code) 407 void set_live(size_t pos) {
411 : live_(l.live_) { 408 if (live_.size() <= pos) live_.resize(std::max(pos + 1, 2 * live_.size()));
412 live_.set(code); 409 live_[pos] = true;
410 }
411
412 bool is_live(size_t pos) const {
413 return unreachable_ || (live_.size() > pos && live_[pos]);
414 }
415
416 Environment& operator|=(const Environment& o) {
417 unreachable_ |= o.unreachable_;
418 for (size_t i = 0, e = o.live_.size(); i < e; ++i) {
Vyacheslav Egorov (Google) 2017/02/15 15:59:36 if one of the envs is unreachable we should just m
419 if (o.live_[i]) set_live(i);
420 }
421 return *this;
422 }
423
424 Environment& operator&=(const Environment& o) {
425 unreachable_ &= o.unreachable_;
426 size_t size = std::min(live_.size(), o.live_.size());
Vyacheslav Egorov (Google) 2017/02/15 15:48:15 This seems highly suspicious: if o.unreachable_
Vyacheslav Egorov (Google) 2017/02/15 15:59:36 Clarification: the same problem with o and this. I
427 if (live_.size() > size) live_.resize(size);
428 for (size_t i = 0; i < size; ++i) {
429 if (live_[i] && (i > o.live_.size() || !o.live_[i])) live_[i] = false;
430 }
431 return *this;
413 } 432 }
414 433
415 static SymbolTable symbol_table_; 434 static SymbolTable symbol_table_;
416 static std::vector<Environment* > envs_; 435 static std::vector<Environment*> envs_;
417 436
418 static const int kMaxNumberOfLocals = 256; 437 std::vector<bool> live_;
419 std::bitset<kMaxNumberOfLocals> live_; 438 bool unreachable_ = false;
420 439
421 friend class ExprEffect; 440 friend class ExprEffect;
422 friend class CallProps; 441 friend class CallProps;
423 }; 442 };
424 443
425 444
426 class CallProps { 445 class CallProps {
427 public: 446 public:
428 CallProps() : env_(NULL) { } 447 CallProps() : env_(NULL) { }
429 448
430 void SetEffect(int arg, ExprEffect in) { 449 void SetEffect(int arg, ExprEffect in) {
431 if (in.hasGC()) gc_.set(arg); 450 if (in.hasGC()) gc_.set(arg);
432 if (in.hasRawDef()) raw_def_.set(arg); 451 if (in.hasRawDef()) raw_def_.set(arg);
433 if (in.hasRawUse()) raw_use_.set(arg); 452 if (in.hasRawUse()) raw_use_.set(arg);
434 if (in.env() != NULL) { 453 if (in.env() != NULL) {
435 if (env_ == NULL) env_ = in.env(); 454 if (env_ == NULL) {
436 env_->live_ |= in.env()->live_; 455 env_ = in.env();
456 } else {
457 *env_ |= *in.env();
458 }
437 } 459 }
438 } 460 }
439 461
440 ExprEffect ComputeCumulativeEffect(bool result_is_raw) { 462 ExprEffect ComputeCumulativeEffect(bool result_is_raw) {
441 ExprEffect out = ExprEffect::NoneWithEnv(env_); 463 ExprEffect out = ExprEffect::NoneWithEnv(env_);
442 if (gc_.any()) out.setGC(); 464 if (gc_.any()) out.setGC();
443 if (raw_use_.any()) out.setRawUse(); 465 if (raw_use_.any()) out.setRawUse();
444 if (result_is_raw) out.setRawDef(); 466 if (result_is_raw) out.setRawDef();
445 return out; 467 return out;
446 } 468 }
447 469
448 bool IsSafe() { 470 bool IsSafe() {
449 if (!gc_.any()) return true; 471 if (!gc_.any()) return true;
450 std::bitset<kMaxNumberOfArguments> raw = (raw_def_ | raw_use_); 472 std::bitset<kMaxNumberOfArguments> raw = (raw_def_ | raw_use_);
451 if (!raw.any()) return true; 473 if (!raw.any()) return true;
452 return gc_.count() == 1 && !((raw ^ gc_).any()); 474 return gc_.count() == 1 && !((raw ^ gc_).any());
453 } 475 }
454 476
455 private: 477 private:
456 static const int kMaxNumberOfArguments = 64; 478 static const int kMaxNumberOfArguments = 64;
457 std::bitset<kMaxNumberOfArguments> raw_def_; 479 std::bitset<kMaxNumberOfArguments> raw_def_;
458 std::bitset<kMaxNumberOfArguments> raw_use_; 480 std::bitset<kMaxNumberOfArguments> raw_use_;
459 std::bitset<kMaxNumberOfArguments> gc_; 481 std::bitset<kMaxNumberOfArguments> gc_;
460 Environment* env_; 482 Environment* env_;
461 }; 483 };
462 484
463 485
464 Environment::SymbolTable Environment::symbol_table_; 486 Environment::SymbolTable Environment::symbol_table_;
465 std::vector<Environment* > Environment::envs_; 487 std::vector<Environment*> Environment::envs_;
466
467 488
468 ExprEffect ExprEffect::Merge(ExprEffect a, ExprEffect b) { 489 ExprEffect ExprEffect::Merge(ExprEffect a, ExprEffect b) {
469 Environment* a_env = a.env(); 490 Environment* a_env = a.env();
470 Environment* b_env = b.env(); 491 Environment* b_env = b.env();
471 Environment* out = NULL; 492 Environment* out = NULL;
472 if (a_env != NULL && b_env != NULL) { 493 if (a_env != NULL && b_env != NULL) {
473 out = Environment::Allocate(*a_env); 494 out = Environment::Allocate(*a_env);
474 out->live_ &= b_env->live_; 495 *out &= *b_env;
475 } 496 }
476 return ExprEffect(a.effect_ | b.effect_, out); 497 return ExprEffect(a.effect_ | b.effect_, out);
477 } 498 }
478 499
479 500
480 ExprEffect ExprEffect::MergeSeq(ExprEffect a, ExprEffect b) { 501 ExprEffect ExprEffect::MergeSeq(ExprEffect a, ExprEffect b) {
481 Environment* a_env = b.hasGC() ? NULL : a.env(); 502 Environment* a_env = b.hasGC() ? NULL : a.env();
482 Environment* b_env = b.env(); 503 Environment* b_env = b.env();
483 Environment* out = (b_env == NULL) ? a_env : b_env; 504 Environment* out = (b_env == NULL) ? a_env : b_env;
484 if (a_env != NULL && b_env != NULL) { 505 if (a_env != NULL && b_env != NULL) {
485 out = Environment::Allocate(*b_env); 506 out = Environment::Allocate(*b_env);
486 out->live_ |= a_env->live_; 507 *out |= *a_env;
487 } 508 }
488 return ExprEffect(a.effect_ | b.effect_, out); 509 return ExprEffect(a.effect_ | b.effect_, out);
489 } 510 }
490 511
491 512
492 ExprEffect ExprEffect::Define(const std::string& name) { 513 ExprEffect ExprEffect::Define(const std::string& name) {
493 Environment* e = env(); 514 Environment* e = env();
494 if (e == NULL) { 515 if (e == NULL) {
495 e = Environment::Allocate(Environment()); 516 e = Environment::Allocate(Environment());
496 } 517 }
(...skipping 761 matching lines...) Expand 10 before | Expand all | Expand 10 after
1258 1279
1259 1280
1260 } 1281 }
1261 1282
1262 static clang::FrontendPluginRegistry::Add<Action<ProblemsFinder> > 1283 static clang::FrontendPluginRegistry::Add<Action<ProblemsFinder> >
1263 FindProblems("find-problems", "Find GC-unsafe places."); 1284 FindProblems("find-problems", "Find GC-unsafe places.");
1264 1285
1265 static clang::FrontendPluginRegistry::Add< 1286 static clang::FrontendPluginRegistry::Add<
1266 Action<FunctionDeclarationFinder> > 1287 Action<FunctionDeclarationFinder> >
1267 DumpCallees("dump-callees", "Dump callees for each function."); 1288 DumpCallees("dump-callees", "Dump callees for each function.");
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698