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

Side by Side Diff: src/IceGlobalInits.h

Issue 1776473007: Subzero. Allocate global initializers from a dedicated arena. (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: fixes ther llvm2ice converter; fixes the VariableDeclarationList destructor. Created 4 years, 9 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/IceGlobalInits.h - Global declarations -------*- C++ -*-===// 1 //===- subzero/src/IceGlobalInits.h - Global declarations -------*- 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 /// \file 10 /// \file
(...skipping 202 matching lines...) Expand 10 before | Expand all | Expand 10 after
213 Initializer &operator=(const Initializer &) = delete; 213 Initializer &operator=(const Initializer &) = delete;
214 214
215 public: 215 public:
216 /// Discriminator for LLVM-style RTTI. 216 /// Discriminator for LLVM-style RTTI.
217 enum InitializerKind { 217 enum InitializerKind {
218 DataInitializerKind, 218 DataInitializerKind,
219 ZeroInitializerKind, 219 ZeroInitializerKind,
220 RelocInitializerKind 220 RelocInitializerKind
221 }; 221 };
222 InitializerKind getKind() const { return Kind; } 222 InitializerKind getKind() const { return Kind; }
223 virtual ~Initializer() = default;
224 virtual SizeT getNumBytes() const = 0; 223 virtual SizeT getNumBytes() const = 0;
225 virtual void dump(Ostream &Stream) const = 0; 224 virtual void dump(Ostream &Stream) const = 0;
226 virtual void dumpType(Ostream &Stream) const; 225 virtual void dumpType(Ostream &Stream) const;
227 226
228 protected: 227 protected:
229 explicit Initializer(InitializerKind Kind) : Kind(Kind) {} 228 explicit Initializer(InitializerKind Kind) : Kind(Kind) {}
230 229
231 private: 230 private:
232 const InitializerKind Kind; 231 const InitializerKind Kind;
233 }; 232 };
233 static_assert(std::is_trivially_destructible<Initializer>::value,
234 "Initializer must be trivially destructible.");
234 235
235 /// Models the data in a data initializer. 236 /// Models the data in a data initializer.
236 using DataVecType = std::vector<char>; 237 using DataVecType = char *;
237 238
238 /// Defines a sequence of byte values as a data initializer. 239 /// Defines a sequence of byte values as a data initializer.
239 class DataInitializer : public Initializer { 240 class DataInitializer : public Initializer {
240 DataInitializer(const DataInitializer &) = delete; 241 DataInitializer(const DataInitializer &) = delete;
241 DataInitializer &operator=(const DataInitializer &) = delete; 242 DataInitializer &operator=(const DataInitializer &) = delete;
242 243
243 public: 244 public:
244 template <class... Args> 245 template <typename T, class... Args>
245 static std::unique_ptr<DataInitializer> create(Args &&... TheArgs) { 246 static DataInitializer *create(T *AllocOwner, Args &&... TheArgs) {
246 return makeUnique<DataInitializer>(std::forward<Args>(TheArgs)...); 247 return new (AllocOwner->template allocate_initializer<DataInitializer>())
248 DataInitializer(AllocOwner, std::forward<Args>(TheArgs)...);
247 } 249 }
248 250
249 const DataVecType &getContents() const { return Contents; } 251 const llvm::StringRef getContents() const {
250 SizeT getNumBytes() const final { return Contents.size(); } 252 return llvm::StringRef(Contents, ContentsSize);
253 }
254 SizeT getNumBytes() const final { return ContentsSize; }
251 void dump(Ostream &Stream) const final; 255 void dump(Ostream &Stream) const final;
252 static bool classof(const Initializer *D) { 256 static bool classof(const Initializer *D) {
253 return D->getKind() == DataInitializerKind; 257 return D->getKind() == DataInitializerKind;
254 } 258 }
255 259
256 private: 260 private:
257 ENABLE_MAKE_UNIQUE; 261 template <typename T>
258 262 DataInitializer(T *AllocOwner,
259 DataInitializer(const llvm::NaClBitcodeRecord::RecordVector &Values) 263 const llvm::NaClBitcodeRecord::RecordVector &Values)
260 : Initializer(DataInitializerKind), Contents(Values.size()) { 264 : Initializer(DataInitializerKind), ContentsSize(Values.size()),
265 // ugh, we should actually do new char[], but this may involve
266 // implementation-specific details. Given that Contents is arena
267 // allocated, and never detele[]d, just use char --
268 // AllocOwner->allocate_array will allocate a buffer with the right
269 // size.
270 Contents(new (AllocOwner->template allocate_initializer<char>(
271 ContentsSize)) char) {
261 for (SizeT I = 0; I < Values.size(); ++I) 272 for (SizeT I = 0; I < Values.size(); ++I)
262 Contents[I] = static_cast<int8_t>(Values[I]); 273 Contents[I] = static_cast<int8_t>(Values[I]);
263 } 274 }
264 275
265 DataInitializer(const char *Str, size_t StrLen) 276 template <typename T>
266 : Initializer(DataInitializerKind), Contents(StrLen) { 277 DataInitializer(T *AllocOwner, const char *Str, size_t StrLen)
278 : Initializer(DataInitializerKind), ContentsSize(StrLen),
279 Contents(new (AllocOwner->template allocate_initializer<char>(
280 ContentsSize)) char) {
267 for (size_t i = 0; i < StrLen; ++i) 281 for (size_t i = 0; i < StrLen; ++i)
268 Contents[i] = Str[i]; 282 Contents[i] = Str[i];
269 } 283 }
270 284
271 /// The byte contents of the data initializer. 285 /// The byte contents of the data initializer.
286 const SizeT ContentsSize;
272 DataVecType Contents; 287 DataVecType Contents;
273 }; 288 };
289 static_assert(std::is_trivially_destructible<DataInitializer>::value,
290 "DataInitializer must be trivially destructible.");
274 291
275 /// Defines a sequence of bytes initialized to zero. 292 /// Defines a sequence of bytes initialized to zero.
276 class ZeroInitializer : public Initializer { 293 class ZeroInitializer : public Initializer {
277 ZeroInitializer(const ZeroInitializer &) = delete; 294 ZeroInitializer(const ZeroInitializer &) = delete;
278 ZeroInitializer &operator=(const ZeroInitializer &) = delete; 295 ZeroInitializer &operator=(const ZeroInitializer &) = delete;
279 296
280 public: 297 public:
281 static std::unique_ptr<ZeroInitializer> create(SizeT Size) { 298 template <typename T>
282 return makeUnique<ZeroInitializer>(Size); 299 static ZeroInitializer *create(T *AllocOwner, SizeT Size) {
300 return new (AllocOwner->template allocate_initializer<ZeroInitializer>())
301 ZeroInitializer(Size);
283 } 302 }
284 SizeT getNumBytes() const final { return Size; } 303 SizeT getNumBytes() const final { return Size; }
285 void dump(Ostream &Stream) const final; 304 void dump(Ostream &Stream) const final;
286 static bool classof(const Initializer *Z) { 305 static bool classof(const Initializer *Z) {
287 return Z->getKind() == ZeroInitializerKind; 306 return Z->getKind() == ZeroInitializerKind;
288 } 307 }
289 308
290 private: 309 private:
291 ENABLE_MAKE_UNIQUE;
292
293 explicit ZeroInitializer(SizeT Size) 310 explicit ZeroInitializer(SizeT Size)
294 : Initializer(ZeroInitializerKind), Size(Size) {} 311 : Initializer(ZeroInitializerKind), Size(Size) {}
295 312
296 /// The number of bytes to be zero initialized. 313 /// The number of bytes to be zero initialized.
297 SizeT Size; 314 SizeT Size;
298 }; 315 };
316 static_assert(std::is_trivially_destructible<ZeroInitializer>::value,
317 "ZeroInitializer must be trivially destructible.");
299 318
300 /// Defines the relocation value of another global declaration. 319 /// Defines the relocation value of another global declaration.
301 class RelocInitializer : public Initializer { 320 class RelocInitializer : public Initializer {
302 RelocInitializer(const RelocInitializer &) = delete; 321 RelocInitializer(const RelocInitializer &) = delete;
303 RelocInitializer &operator=(const RelocInitializer &) = delete; 322 RelocInitializer &operator=(const RelocInitializer &) = delete;
304 323
305 public: 324 public:
306 static std::unique_ptr<RelocInitializer> 325 template <typename T>
307 create(const GlobalDeclaration *Declaration, 326 static RelocInitializer *create(T *AllocOwner,
308 const RelocOffsetArray &OffsetExpr) { 327 const GlobalDeclaration *Declaration,
328 const RelocOffsetArray &OffsetExpr) {
309 constexpr bool NoFixup = false; 329 constexpr bool NoFixup = false;
310 return makeUnique<RelocInitializer>(Declaration, OffsetExpr, NoFixup); 330 return new (AllocOwner->template allocate_initializer<RelocInitializer>())
331 RelocInitializer(AllocOwner, Declaration, OffsetExpr, NoFixup);
311 } 332 }
312 333
313 static std::unique_ptr<RelocInitializer> 334 template <typename T>
314 create(const GlobalDeclaration *Declaration, 335 static RelocInitializer *
336 create(T *AllocOwner, const GlobalDeclaration *Declaration,
315 const RelocOffsetArray &OffsetExpr, FixupKind Fixup) { 337 const RelocOffsetArray &OffsetExpr, FixupKind Fixup) {
316 constexpr bool HasFixup = true; 338 constexpr bool HasFixup = true;
317 return makeUnique<RelocInitializer>(Declaration, OffsetExpr, HasFixup, 339 return new (AllocOwner->template allocate_initializer<RelocInitializer>())
318 Fixup); 340 RelocInitializer(AllocOwner, Declaration, OffsetExpr, HasFixup,
341 Fixup);
319 } 342 }
320 343
321 RelocOffsetT getOffset() const { 344 RelocOffsetT getOffset() const {
322 RelocOffsetT Offset = 0; 345 RelocOffsetT Offset = 0;
323 for (const auto *RelocOffset : OffsetExpr) { 346 for (SizeT i = 0; i < OffsetExprSize; ++i) {
324 Offset += RelocOffset->getOffset(); 347 Offset += OffsetExpr[i]->getOffset();
325 } 348 }
326 return Offset; 349 return Offset;
327 } 350 }
328 351
329 bool hasFixup() const { return HasFixup; } 352 bool hasFixup() const { return HasFixup; }
330 FixupKind getFixup() const { 353 FixupKind getFixup() const {
331 assert(HasFixup); 354 assert(HasFixup);
332 return Fixup; 355 return Fixup;
333 } 356 }
334 357
335 const GlobalDeclaration *getDeclaration() const { return Declaration; } 358 const GlobalDeclaration *getDeclaration() const { return Declaration; }
336 SizeT getNumBytes() const final { return RelocAddrSize; } 359 SizeT getNumBytes() const final { return RelocAddrSize; }
337 void dump(Ostream &Stream) const final; 360 void dump(Ostream &Stream) const final;
338 void dumpType(Ostream &Stream) const final; 361 void dumpType(Ostream &Stream) const final;
339 static bool classof(const Initializer *R) { 362 static bool classof(const Initializer *R) {
340 return R->getKind() == RelocInitializerKind; 363 return R->getKind() == RelocInitializerKind;
341 } 364 }
342 365
343 private: 366 private:
344 ENABLE_MAKE_UNIQUE; 367 template <typename T>
345 368 RelocInitializer(T *AllocOwner, const GlobalDeclaration *Declaration,
346 RelocInitializer(const GlobalDeclaration *Declaration,
347 const RelocOffsetArray &OffsetExpr, bool HasFixup, 369 const RelocOffsetArray &OffsetExpr, bool HasFixup,
348 FixupKind Fixup = 0) 370 FixupKind Fixup = 0)
349 : Initializer(RelocInitializerKind), 371 : Initializer(RelocInitializerKind),
350 Declaration(Declaration), // The global declaration used in the reloc. 372 Declaration(Declaration), // The global declaration used in the reloc.
351 OffsetExpr(OffsetExpr), HasFixup(HasFixup), Fixup(Fixup) {} 373 OffsetExprSize(OffsetExpr.size()),
374 OffsetExpr(
375 new (AllocOwner->template allocate_initializer<RelocOffset *>(
376 OffsetExprSize)) RelocOffset *),
377 HasFixup(HasFixup), Fixup(Fixup) {
378 for (SizeT i = 0; i < OffsetExprSize; ++i) {
379 this->OffsetExpr[i] = OffsetExpr[i];
380 }
381 }
352 382
353 const GlobalDeclaration *Declaration; 383 const GlobalDeclaration *Declaration;
354 /// The offset to add to the relocation. 384 /// The offset to add to the relocation.
355 const RelocOffsetArray OffsetExpr; 385 const SizeT OffsetExprSize;
386 RelocOffset **OffsetExpr;
356 const bool HasFixup = false; 387 const bool HasFixup = false;
357 const FixupKind Fixup = 0; 388 const FixupKind Fixup = 0;
358 }; 389 };
390 static_assert(std::is_trivially_destructible<RelocInitializer>::value,
391 "RelocInitializer must be trivially destructible.");
359 392
360 /// Models the list of initializers. 393 /// Models the list of initializers.
361 using InitializerListType = std::vector<std::unique_ptr<Initializer>>; 394 // TODO(jpp): missing allocator.
395 using InitializerListType = std::vector<Initializer *>;
362 396
363 static VariableDeclaration *create(GlobalContext *Context, 397 template <typename T>
398 static VariableDeclaration *create(T *AllocOwner,
364 bool SuppressMangling = false, 399 bool SuppressMangling = false,
365 llvm::GlobalValue::LinkageTypes Linkage = 400 llvm::GlobalValue::LinkageTypes Linkage =
366 llvm::GlobalValue::InternalLinkage) { 401 llvm::GlobalValue::InternalLinkage) {
367 return new (Context->allocate<VariableDeclaration>()) 402 return new (
403 AllocOwner
404 ->template allocate_variable_declaration<VariableDeclaration>())
368 VariableDeclaration(Linkage, SuppressMangling); 405 VariableDeclaration(Linkage, SuppressMangling);
369 } 406 }
370 static VariableDeclaration *createExternal(GlobalContext *Context) { 407
408 template <typename T>
409 static VariableDeclaration *createExternal(T *AllocOwner) {
371 constexpr bool SuppressMangling = true; 410 constexpr bool SuppressMangling = true;
372 constexpr llvm::GlobalValue::LinkageTypes Linkage = 411 constexpr llvm::GlobalValue::LinkageTypes Linkage =
373 llvm::GlobalValue::ExternalLinkage; 412 llvm::GlobalValue::ExternalLinkage;
374 return create(Context, SuppressMangling, Linkage); 413 return create(AllocOwner, SuppressMangling, Linkage);
375 } 414 }
376 415
377 const InitializerListType &getInitializers() const { return *Initializers; } 416 const InitializerListType &getInitializers() const { return Initializers; }
378 bool getIsConstant() const { return IsConstant; } 417 bool getIsConstant() const { return IsConstant; }
379 void setIsConstant(bool NewValue) { IsConstant = NewValue; } 418 void setIsConstant(bool NewValue) { IsConstant = NewValue; }
380 uint32_t getAlignment() const { return Alignment; } 419 uint32_t getAlignment() const { return Alignment; }
381 void setAlignment(uint32_t NewAlignment) { Alignment = NewAlignment; } 420 void setAlignment(uint32_t NewAlignment) { Alignment = NewAlignment; }
382 bool hasInitializer() const { return HasInitializer; } 421 bool hasInitializer() const { return HasInitializer; }
383 bool hasNonzeroInitializer() const { 422 bool hasNonzeroInitializer() const {
384 return !(Initializers->size() == 1 && 423 return !(Initializers.size() == 1 &&
385 llvm::isa<ZeroInitializer>((*Initializers)[0].get())); 424 llvm::isa<ZeroInitializer>(Initializers[0]));
386 } 425 }
387 426
388 /// Returns the number of bytes for the initializer of the global address. 427 /// Returns the number of bytes for the initializer of the global address.
389 SizeT getNumBytes() const { 428 SizeT getNumBytes() const {
390 SizeT Count = 0; 429 SizeT Count = 0;
391 for (const std::unique_ptr<Initializer> &Init : *Initializers) { 430 for (const auto *Init : Initializers) {
392 Count += Init->getNumBytes(); 431 Count += Init->getNumBytes();
393 } 432 }
394 return Count; 433 return Count;
395 } 434 }
396 435
397 /// Adds Initializer to the list of initializers. Takes ownership of the 436 /// Adds Initializer to the list of initializers. Takes ownership of the
398 /// initializer. 437 /// initializer.
399 void addInitializer(std::unique_ptr<Initializer> Initializer) { 438 void addInitializer(Initializer *Initializer) {
400 const bool OldSuppressMangling = getSuppressMangling(); 439 const bool OldSuppressMangling = getSuppressMangling();
401 Initializers->emplace_back(std::move(Initializer)); 440 Initializers.emplace_back(Initializer);
402 HasInitializer = true; 441 HasInitializer = true;
403 // The getSuppressMangling() logic depends on whether the global variable 442 // The getSuppressMangling() logic depends on whether the global variable
404 // has initializers. If its value changed as a result of adding an 443 // has initializers. If its value changed as a result of adding an
405 // initializer, then make sure we haven't previously set the name based on 444 // initializer, then make sure we haven't previously set the name based on
406 // faulty SuppressMangling logic. 445 // faulty SuppressMangling logic.
407 const bool SameMangling = (OldSuppressMangling == getSuppressMangling()); 446 const bool SameMangling = (OldSuppressMangling == getSuppressMangling());
408 (void)SameMangling; 447 (void)SameMangling;
409 assert(!Name.empty() || SameMangling); 448 assert(!Name.empty() || SameMangling);
410 } 449 }
411 450
(...skipping 12 matching lines...) Expand all
424 static bool classof(const GlobalDeclaration *Addr) { 463 static bool classof(const GlobalDeclaration *Addr) {
425 return Addr->getKind() == VariableDeclarationKind; 464 return Addr->getKind() == VariableDeclarationKind;
426 } 465 }
427 466
428 bool getSuppressMangling() const final { 467 bool getSuppressMangling() const final {
429 if (ForceSuppressMangling) 468 if (ForceSuppressMangling)
430 return true; 469 return true;
431 return isExternal() && !hasInitializer(); 470 return isExternal() && !hasInitializer();
432 } 471 }
433 472
434 void discardInitializers() { Initializers = nullptr; } 473 void discardInitializers() { Initializers.clear(); }
435 474
436 private: 475 private:
437 /// List of initializers for the declared variable. 476 /// List of initializers for the declared variable.
438 std::unique_ptr<InitializerListType> Initializers; 477 InitializerListType Initializers;
439 bool HasInitializer = false; 478 bool HasInitializer = false;
440 /// The alignment of the declared variable. 479 /// The alignment of the declared variable.
441 uint32_t Alignment = 0; 480 uint32_t Alignment = 0;
442 /// True if a declared (global) constant. 481 /// True if a declared (global) constant.
443 bool IsConstant = false; 482 bool IsConstant = false;
444 /// If set to true, force getSuppressMangling() to return true. 483 /// If set to true, force getSuppressMangling() to return true.
445 const bool ForceSuppressMangling; 484 const bool ForceSuppressMangling;
446 485
447 VariableDeclaration(llvm::GlobalValue::LinkageTypes Linkage, 486 VariableDeclaration(llvm::GlobalValue::LinkageTypes Linkage,
448 bool SuppressMangling) 487 bool SuppressMangling)
449 : GlobalDeclaration(VariableDeclarationKind, Linkage), 488 : GlobalDeclaration(VariableDeclarationKind, Linkage),
450 Initializers(new InitializerListType),
451 ForceSuppressMangling(SuppressMangling) {} 489 ForceSuppressMangling(SuppressMangling) {}
452 }; 490 };
453 491
454 template <class StreamType> 492 template <class StreamType>
455 inline StreamType &operator<<(StreamType &Stream, 493 inline StreamType &operator<<(StreamType &Stream,
456 const VariableDeclaration::Initializer &Init) { 494 const VariableDeclaration::Initializer &Init) {
457 Init.dump(Stream); 495 Init.dump(Stream);
458 return Stream; 496 return Stream;
459 } 497 }
460 498
461 template <class StreamType> 499 template <class StreamType>
462 inline StreamType &operator<<(StreamType &Stream, 500 inline StreamType &operator<<(StreamType &Stream,
463 const GlobalDeclaration &Addr) { 501 const GlobalDeclaration &Addr) {
464 Addr.dump(Stream); 502 Addr.dump(Stream);
465 return Stream; 503 return Stream;
466 } 504 }
467 505
468 } // end of namespace Ice 506 } // end of namespace Ice
469 507
470 #endif // SUBZERO_SRC_ICEGLOBALINITS_H 508 #endif // SUBZERO_SRC_ICEGLOBALINITS_H
OLDNEW
« src/IceDefs.h ('K') | « src/IceGlobalContext.cpp ('k') | src/IceGlobalInits.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698