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

Side by Side Diff: src/IceGlobalContext.h

Issue 1181013016: Subzero. Fixes memory leaks. (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: clang-format: for f in $(git diff --name-only HEAD~7); do if [[ ${f} == *h || ${f} == *cpp ]]; then… Created 5 years, 6 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 //===- subzero/src/IceGlobalContext.h - Global context defs -----*- C++ -*-===// 1 //===- subzero/src/IceGlobalContext.h - Global context defs -----*- C++ -*-===//
2 // 2 //
3 // The Subzero Code Generator 3 // The Subzero Code Generator
4 // 4 //
5 // This file is distributed under the University of Illinois Open Source 5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details. 6 // License. See LICENSE.TXT for details.
7 // 7 //
8 //===----------------------------------------------------------------------===// 8 //===----------------------------------------------------------------------===//
9 // 9 //
10 // This file declares aspects of the compilation that persist across 10 // This file declares aspects of the compilation that persist across
11 // multiple functions. 11 // multiple functions.
12 // 12 //
13 //===----------------------------------------------------------------------===// 13 //===----------------------------------------------------------------------===//
14 14
15 #ifndef SUBZERO_SRC_ICEGLOBALCONTEXT_H 15 #ifndef SUBZERO_SRC_ICEGLOBALCONTEXT_H
16 #define SUBZERO_SRC_ICEGLOBALCONTEXT_H 16 #define SUBZERO_SRC_ICEGLOBALCONTEXT_H
17 17
18 #include <array> 18 #include <array>
19 #include <functional>
19 #include <mutex> 20 #include <mutex>
20 #include <thread> 21 #include <thread>
22 #include <type_traits>
23 #include <vector>
21 24
22 #include "IceDefs.h" 25 #include "IceDefs.h"
23 #include "IceClFlags.h" 26 #include "IceClFlags.h"
24 #include "IceIntrinsics.h" 27 #include "IceIntrinsics.h"
25 #include "IceRNG.h" 28 #include "IceRNG.h"
26 #include "IceThreading.h" 29 #include "IceThreading.h"
27 #include "IceTimerTree.h" 30 #include "IceTimerTree.h"
28 #include "IceTypes.h" 31 #include "IceTypes.h"
29 #include "IceUtils.h" 32 #include "IceUtils.h"
30 33
(...skipping 172 matching lines...) Expand 10 before | Expand all | Expand 10 after
203 ConstantList getConstantPool(Type Ty); 206 ConstantList getConstantPool(Type Ty);
204 // Returns a copy of the list of external symbols. 207 // Returns a copy of the list of external symbols.
205 ConstantList getConstantExternSyms(); 208 ConstantList getConstantExternSyms();
206 209
207 const ClFlags &getFlags() const { return Flags; } 210 const ClFlags &getFlags() const { return Flags; }
208 211
209 bool isIRGenerationDisabled() const { 212 bool isIRGenerationDisabled() const {
210 return getFlags().getDisableIRGeneration(); 213 return getFlags().getDisableIRGeneration();
211 } 214 }
212 215
213 // Allocate data of type T using the global allocator. 216 // Allocate data of type T using the global allocator. We allow entites
Jim Stichnoth 2015/06/19 23:09:25 entities
214 template <typename T> T *allocate() { return getAllocator()->Allocate<T>(); } 217 // allocated from this global allocator to be either trivially and
Jim Stichnoth 2015/06/19 23:09:25 either ... or
John 2015/06/20 00:10:33 Done.
218 // non-trivially destructible. We optimize the case when T is trivially
219 // destructible by not registering a destructor. Destructors will be invoked
220 // during GlobalContext destruction in the reverse object creation order.
221 template <typename T>
222 typename std::enable_if<std::is_trivially_destructible<T>::value, T>::type *
Jim Stichnoth 2015/06/19 23:09:25 This is a cool trick, but I feel that the user mig
John 2015/06/20 00:10:33 And that's fine. This allocator, essentially, "rep
Jim Stichnoth 2015/06/21 00:15:48 OK, I buy that.
223 allocate() {
224 return getAllocator()->Allocate<T>();
225 }
226
227 template <typename T>
228 typename std::enable_if<!std::is_trivially_destructible<T>::value, T>::type *
229 allocate() {
230 T *Ret = getAllocator()->Allocate<T>();
231 getDestructors()->emplace_back([Ret]() { Ret->~T(); });
232 return Ret;
233 }
215 234
216 const Intrinsics &getIntrinsicsInfo() const { return IntrinsicsInfo; } 235 const Intrinsics &getIntrinsicsInfo() const { return IntrinsicsInfo; }
217 236
218 // TODO(wala,stichnot): Make the RNG play nicely with multithreaded 237 // TODO(wala,stichnot): Make the RNG play nicely with multithreaded
219 // translation. 238 // translation.
220 RandomNumberGenerator &getRNG() { return RNG; } 239 RandomNumberGenerator &getRNG() { return RNG; }
221 240
222 ELFObjectWriter *getObjectWriter() const { return ObjectWriter.get(); } 241 ELFObjectWriter *getObjectWriter() const { return ObjectWriter.get(); }
223 242
224 // Reset stats at the beginning of a function. 243 // Reset stats at the beginning of a function.
(...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after
375 394
376 // Emitter thread startup routine. 395 // Emitter thread startup routine.
377 void emitterWrapper(ThreadContext *MyTLS) { 396 void emitterWrapper(ThreadContext *MyTLS) {
378 ICE_TLS_SET_FIELD(TLS, MyTLS); 397 ICE_TLS_SET_FIELD(TLS, MyTLS);
379 emitItems(); 398 emitItems();
380 } 399 }
381 // Emit functions and global initializers from the emitter queue 400 // Emit functions and global initializers from the emitter queue
382 // until the queue is empty. 401 // until the queue is empty.
383 void emitItems(); 402 void emitItems();
384 403
385 // Uses DataLowering to lower Globals. As a side effect, clears the Globals 404 // Uses DataLowering to lower Globals. Side effects:
386 // array. 405 // - discards the initializer list for the global variable in Globals.
406 // - clears the Globals array.
387 void lowerGlobals(const IceString &SectionSuffix); 407 void lowerGlobals(const IceString &SectionSuffix);
388 408
389 // Lowers the profile information. 409 // Lowers the profile information.
390 void lowerProfileData(); 410 void lowerProfileData();
391 411
392 // Utility function to match a symbol name against a match string. 412 // Utility function to match a symbol name against a match string.
393 // This is used in a few cases where we want to take some action on 413 // This is used in a few cases where we want to take some action on
394 // a particular function or symbol based on a command-line argument, 414 // a particular function or symbol based on a command-line argument,
395 // such as changing the verbose level for a particular function. An 415 // such as changing the verbose level for a particular function. An
396 // empty Match argument means match everything. Returns true if 416 // empty Match argument means match everything. Returns true if
397 // there is a match. 417 // there is a match.
398 static bool matchSymbolName(const IceString &SymbolName, 418 static bool matchSymbolName(const IceString &SymbolName,
399 const IceString &Match) { 419 const IceString &Match) {
400 return Match.empty() || Match == SymbolName; 420 return Match.empty() || Match == SymbolName;
401 } 421 }
402 422
403 private: 423 private:
404 // Try to ensure mutexes are allocated on separate cache lines. 424 // Try to ensure mutexes are allocated on separate cache lines.
405 425
426 // Destructors collaborate with Allocator
406 ICE_CACHELINE_BOUNDARY; 427 ICE_CACHELINE_BOUNDARY;
407 // Managed by getAllocator() 428 // Managed by getAllocator()
408 GlobalLockType AllocLock; 429 GlobalLockType AllocLock;
409 ArenaAllocator<> Allocator; 430 ArenaAllocator<> Allocator;
410 431
411 ICE_CACHELINE_BOUNDARY; 432 ICE_CACHELINE_BOUNDARY;
433 // Managed by getDestructors()
434 typedef std::vector<std::function<void()>> DestructorArray;
435 GlobalLockType DestructorsLock;
436 DestructorArray Destructors;
437
438 ICE_CACHELINE_BOUNDARY;
412 // Managed by getConstantPool() 439 // Managed by getConstantPool()
413 GlobalLockType ConstPoolLock; 440 GlobalLockType ConstPoolLock;
414 std::unique_ptr<ConstantPool> ConstPool; 441 std::unique_ptr<ConstantPool> ConstPool;
415 442
416 ICE_CACHELINE_BOUNDARY; 443 ICE_CACHELINE_BOUNDARY;
417 // Managed by getErrorStatus() 444 // Managed by getErrorStatus()
418 GlobalLockType ErrorStatusLock; 445 GlobalLockType ErrorStatusLock;
419 ErrorCode ErrorStatus; 446 ErrorCode ErrorStatus;
420 447
421 ICE_CACHELINE_BOUNDARY; 448 ICE_CACHELINE_BOUNDARY;
(...skipping 27 matching lines...) Expand all
449 // emitItems(), or in IceCompiler::run before the compilation is over.) 476 // emitItems(), or in IceCompiler::run before the compilation is over.)
450 // TODO(jpp): move to EmitterContext. 477 // TODO(jpp): move to EmitterContext.
451 std::unique_ptr<TargetDataLowering> DataLowering; 478 std::unique_ptr<TargetDataLowering> DataLowering;
452 // If !HasEmittedCode, SubZero will accumulate all Globals (which are "true" 479 // If !HasEmittedCode, SubZero will accumulate all Globals (which are "true"
453 // program global variables) until the first code WorkItem is seen. 480 // program global variables) until the first code WorkItem is seen.
454 // TODO(jpp): move to EmitterContext. 481 // TODO(jpp): move to EmitterContext.
455 bool HasSeenCode; 482 bool HasSeenCode;
456 // TODO(jpp): move to EmitterContext. 483 // TODO(jpp): move to EmitterContext.
457 VariableDeclarationList Globals; 484 VariableDeclarationList Globals;
458 // TODO(jpp): move to EmitterContext. 485 // TODO(jpp): move to EmitterContext.
459 std::unique_ptr<VariableDeclaration> ProfileBlockInfoVarDecl; 486 VariableDeclaration *ProfileBlockInfoVarDecl;
460 487
461 LockedPtr<ArenaAllocator<>> getAllocator() { 488 LockedPtr<ArenaAllocator<>> getAllocator() {
462 return LockedPtr<ArenaAllocator<>>(&Allocator, &AllocLock); 489 return LockedPtr<ArenaAllocator<>>(&Allocator, &AllocLock);
463 } 490 }
464 LockedPtr<ConstantPool> getConstPool() { 491 LockedPtr<ConstantPool> getConstPool() {
465 return LockedPtr<ConstantPool>(ConstPool.get(), &ConstPoolLock); 492 return LockedPtr<ConstantPool>(ConstPool.get(), &ConstPoolLock);
466 } 493 }
467 LockedPtr<CodeStats> getStatsCumulative() { 494 LockedPtr<CodeStats> getStatsCumulative() {
468 return LockedPtr<CodeStats>(&StatsCumulative, &StatsLock); 495 return LockedPtr<CodeStats>(&StatsCumulative, &StatsLock);
469 } 496 }
470 LockedPtr<TimerList> getTimers() { 497 LockedPtr<TimerList> getTimers() {
471 return LockedPtr<TimerList>(&Timers, &TimerLock); 498 return LockedPtr<TimerList>(&Timers, &TimerLock);
472 } 499 }
500 LockedPtr<DestructorArray> getDestructors() {
501 return LockedPtr<DestructorArray>(&Destructors, &DestructorsLock);
502 }
473 503
474 void accumulateGlobals(std::unique_ptr<VariableDeclarationList> Globls) { 504 void accumulateGlobals(std::unique_ptr<VariableDeclarationList> Globls) {
475 if (Globls != nullptr) 505 if (Globls != nullptr)
476 Globals.insert(Globals.end(), Globls->begin(), Globls->end()); 506 Globals.insert(Globals.end(), Globls->begin(), Globls->end());
477 } 507 }
478 508
479 void lowerGlobalsIfNoCodeHasBeenSeen() { 509 void lowerGlobalsIfNoCodeHasBeenSeen() {
480 if (HasSeenCode) 510 if (HasSeenCode)
481 return; 511 return;
482 constexpr char NoSuffix[] = ""; 512 constexpr char NoSuffix[] = "";
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
548 explicit OstreamLocker(GlobalContext *Ctx) : Ctx(Ctx) { Ctx->lockStr(); } 578 explicit OstreamLocker(GlobalContext *Ctx) : Ctx(Ctx) { Ctx->lockStr(); }
549 ~OstreamLocker() { Ctx->unlockStr(); } 579 ~OstreamLocker() { Ctx->unlockStr(); }
550 580
551 private: 581 private:
552 GlobalContext *const Ctx; 582 GlobalContext *const Ctx;
553 }; 583 };
554 584
555 } // end of namespace Ice 585 } // end of namespace Ice
556 586
557 #endif // SUBZERO_SRC_ICEGLOBALCONTEXT_H 587 #endif // SUBZERO_SRC_ICEGLOBALCONTEXT_H
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698