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

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: Removes global variable (and initializer) allocation methods from GlobalContext. 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
« no previous file with comments | « src/IceGlobalContext.cpp ('k') | src/IceGlobalInits.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 <class... Args>
245 static std::unique_ptr<DataInitializer> create(Args &&... TheArgs) { 246 static DataInitializer *create(VariableDeclarationList *VDL,
246 return makeUnique<DataInitializer>(std::forward<Args>(TheArgs)...); 247 Args &&... TheArgs) {
248 return new (VDL->allocate_initializer<DataInitializer>())
249 DataInitializer(VDL, std::forward<Args>(TheArgs)...);
247 } 250 }
248 251
249 const DataVecType &getContents() const { return Contents; } 252 const llvm::StringRef getContents() const {
250 SizeT getNumBytes() const final { return Contents.size(); } 253 return llvm::StringRef(Contents, ContentsSize);
254 }
255 SizeT getNumBytes() const final { return ContentsSize; }
251 void dump(Ostream &Stream) const final; 256 void dump(Ostream &Stream) const final;
252 static bool classof(const Initializer *D) { 257 static bool classof(const Initializer *D) {
253 return D->getKind() == DataInitializerKind; 258 return D->getKind() == DataInitializerKind;
254 } 259 }
255 260
256 private: 261 private:
257 ENABLE_MAKE_UNIQUE; 262 DataInitializer(VariableDeclarationList *VDL,
258 263 const llvm::NaClBitcodeRecord::RecordVector &Values)
259 DataInitializer(const llvm::NaClBitcodeRecord::RecordVector &Values) 264 : Initializer(DataInitializerKind), ContentsSize(Values.size()),
260 : Initializer(DataInitializerKind), Contents(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 (VDL->allocate_initializer<char>(ContentsSize)) char) {
261 for (SizeT I = 0; I < Values.size(); ++I) 271 for (SizeT I = 0; I < Values.size(); ++I)
262 Contents[I] = static_cast<int8_t>(Values[I]); 272 Contents[I] = static_cast<int8_t>(Values[I]);
263 } 273 }
264 274
265 DataInitializer(const char *Str, size_t StrLen) 275 DataInitializer(VariableDeclarationList *VDL, const char *Str,
266 : Initializer(DataInitializerKind), Contents(StrLen) { 276 size_t StrLen)
277 : Initializer(DataInitializerKind), ContentsSize(StrLen),
278 Contents(new (VDL->allocate_initializer<char>(ContentsSize)) char) {
267 for (size_t i = 0; i < StrLen; ++i) 279 for (size_t i = 0; i < StrLen; ++i)
268 Contents[i] = Str[i]; 280 Contents[i] = Str[i];
269 } 281 }
270 282
271 /// The byte contents of the data initializer. 283 /// The byte contents of the data initializer.
284 const SizeT ContentsSize;
272 DataVecType Contents; 285 DataVecType Contents;
273 }; 286 };
287 static_assert(std::is_trivially_destructible<DataInitializer>::value,
288 "DataInitializer must be trivially destructible.");
274 289
275 /// Defines a sequence of bytes initialized to zero. 290 /// Defines a sequence of bytes initialized to zero.
276 class ZeroInitializer : public Initializer { 291 class ZeroInitializer : public Initializer {
277 ZeroInitializer(const ZeroInitializer &) = delete; 292 ZeroInitializer(const ZeroInitializer &) = delete;
278 ZeroInitializer &operator=(const ZeroInitializer &) = delete; 293 ZeroInitializer &operator=(const ZeroInitializer &) = delete;
279 294
280 public: 295 public:
281 static std::unique_ptr<ZeroInitializer> create(SizeT Size) { 296 static ZeroInitializer *create(VariableDeclarationList *VDL, SizeT Size) {
282 return makeUnique<ZeroInitializer>(Size); 297 return new (VDL->allocate_initializer<ZeroInitializer>())
298 ZeroInitializer(Size);
283 } 299 }
284 SizeT getNumBytes() const final { return Size; } 300 SizeT getNumBytes() const final { return Size; }
285 void dump(Ostream &Stream) const final; 301 void dump(Ostream &Stream) const final;
286 static bool classof(const Initializer *Z) { 302 static bool classof(const Initializer *Z) {
287 return Z->getKind() == ZeroInitializerKind; 303 return Z->getKind() == ZeroInitializerKind;
288 } 304 }
289 305
290 private: 306 private:
291 ENABLE_MAKE_UNIQUE;
292
293 explicit ZeroInitializer(SizeT Size) 307 explicit ZeroInitializer(SizeT Size)
294 : Initializer(ZeroInitializerKind), Size(Size) {} 308 : Initializer(ZeroInitializerKind), Size(Size) {}
295 309
296 /// The number of bytes to be zero initialized. 310 /// The number of bytes to be zero initialized.
297 SizeT Size; 311 SizeT Size;
298 }; 312 };
313 static_assert(std::is_trivially_destructible<ZeroInitializer>::value,
314 "ZeroInitializer must be trivially destructible.");
299 315
300 /// Defines the relocation value of another global declaration. 316 /// Defines the relocation value of another global declaration.
301 class RelocInitializer : public Initializer { 317 class RelocInitializer : public Initializer {
302 RelocInitializer(const RelocInitializer &) = delete; 318 RelocInitializer(const RelocInitializer &) = delete;
303 RelocInitializer &operator=(const RelocInitializer &) = delete; 319 RelocInitializer &operator=(const RelocInitializer &) = delete;
304 320
305 public: 321 public:
306 static std::unique_ptr<RelocInitializer> 322 static RelocInitializer *create(VariableDeclarationList *VDL,
307 create(const GlobalDeclaration *Declaration, 323 const GlobalDeclaration *Declaration,
308 const RelocOffsetArray &OffsetExpr) { 324 const RelocOffsetArray &OffsetExpr) {
309 constexpr bool NoFixup = false; 325 constexpr bool NoFixup = false;
310 return makeUnique<RelocInitializer>(Declaration, OffsetExpr, NoFixup); 326 return new (VDL->allocate_initializer<RelocInitializer>())
327 RelocInitializer(VDL, Declaration, OffsetExpr, NoFixup);
311 } 328 }
312 329
313 static std::unique_ptr<RelocInitializer> 330 static RelocInitializer *create(VariableDeclarationList *VDL,
314 create(const GlobalDeclaration *Declaration, 331 const GlobalDeclaration *Declaration,
315 const RelocOffsetArray &OffsetExpr, FixupKind Fixup) { 332 const RelocOffsetArray &OffsetExpr,
333 FixupKind Fixup) {
316 constexpr bool HasFixup = true; 334 constexpr bool HasFixup = true;
317 return makeUnique<RelocInitializer>(Declaration, OffsetExpr, HasFixup, 335 return new (VDL->allocate_initializer<RelocInitializer>())
318 Fixup); 336 RelocInitializer(VDL, Declaration, OffsetExpr, HasFixup, Fixup);
319 } 337 }
320 338
321 RelocOffsetT getOffset() const { 339 RelocOffsetT getOffset() const {
322 RelocOffsetT Offset = 0; 340 RelocOffsetT Offset = 0;
323 for (const auto *RelocOffset : OffsetExpr) { 341 for (SizeT i = 0; i < OffsetExprSize; ++i) {
324 Offset += RelocOffset->getOffset(); 342 Offset += OffsetExpr[i]->getOffset();
325 } 343 }
326 return Offset; 344 return Offset;
327 } 345 }
328 346
329 bool hasFixup() const { return HasFixup; } 347 bool hasFixup() const { return HasFixup; }
330 FixupKind getFixup() const { 348 FixupKind getFixup() const {
331 assert(HasFixup); 349 assert(HasFixup);
332 return Fixup; 350 return Fixup;
333 } 351 }
334 352
335 const GlobalDeclaration *getDeclaration() const { return Declaration; } 353 const GlobalDeclaration *getDeclaration() const { return Declaration; }
336 SizeT getNumBytes() const final { return RelocAddrSize; } 354 SizeT getNumBytes() const final { return RelocAddrSize; }
337 void dump(Ostream &Stream) const final; 355 void dump(Ostream &Stream) const final;
338 void dumpType(Ostream &Stream) const final; 356 void dumpType(Ostream &Stream) const final;
339 static bool classof(const Initializer *R) { 357 static bool classof(const Initializer *R) {
340 return R->getKind() == RelocInitializerKind; 358 return R->getKind() == RelocInitializerKind;
341 } 359 }
342 360
343 private: 361 private:
344 ENABLE_MAKE_UNIQUE; 362 RelocInitializer(VariableDeclarationList *VDL,
345 363 const GlobalDeclaration *Declaration,
346 RelocInitializer(const GlobalDeclaration *Declaration,
347 const RelocOffsetArray &OffsetExpr, bool HasFixup, 364 const RelocOffsetArray &OffsetExpr, bool HasFixup,
348 FixupKind Fixup = 0) 365 FixupKind Fixup = 0)
349 : Initializer(RelocInitializerKind), 366 : Initializer(RelocInitializerKind),
350 Declaration(Declaration), // The global declaration used in the reloc. 367 Declaration(Declaration), // The global declaration used in the reloc.
351 OffsetExpr(OffsetExpr), HasFixup(HasFixup), Fixup(Fixup) {} 368 OffsetExprSize(OffsetExpr.size()),
369 OffsetExpr(new (VDL->allocate_initializer<RelocOffset *>(
370 OffsetExprSize)) RelocOffset *),
371 HasFixup(HasFixup), Fixup(Fixup) {
372 for (SizeT i = 0; i < OffsetExprSize; ++i) {
373 this->OffsetExpr[i] = OffsetExpr[i];
374 }
375 }
352 376
353 const GlobalDeclaration *Declaration; 377 const GlobalDeclaration *Declaration;
354 /// The offset to add to the relocation. 378 /// The offset to add to the relocation.
355 const RelocOffsetArray OffsetExpr; 379 const SizeT OffsetExprSize;
380 RelocOffset **OffsetExpr;
356 const bool HasFixup = false; 381 const bool HasFixup = false;
357 const FixupKind Fixup = 0; 382 const FixupKind Fixup = 0;
358 }; 383 };
384 static_assert(std::is_trivially_destructible<RelocInitializer>::value,
385 "RelocInitializer must be trivially destructible.");
359 386
360 /// Models the list of initializers. 387 /// Models the list of initializers.
361 using InitializerListType = std::vector<std::unique_ptr<Initializer>>; 388 // TODO(jpp): missing allocator.
389 using InitializerListType = std::vector<Initializer *>;
362 390
363 static VariableDeclaration *create(GlobalContext *Context, 391 static VariableDeclaration *create(VariableDeclarationList *VDL,
364 bool SuppressMangling = false, 392 bool SuppressMangling = false,
365 llvm::GlobalValue::LinkageTypes Linkage = 393 llvm::GlobalValue::LinkageTypes Linkage =
366 llvm::GlobalValue::InternalLinkage) { 394 llvm::GlobalValue::InternalLinkage) {
367 return new (Context->allocate<VariableDeclaration>()) 395 return new (VDL->allocate_variable_declaration<VariableDeclaration>())
368 VariableDeclaration(Linkage, SuppressMangling); 396 VariableDeclaration(Linkage, SuppressMangling);
369 } 397 }
370 static VariableDeclaration *createExternal(GlobalContext *Context) { 398
399 static VariableDeclaration *createExternal(VariableDeclarationList *VDL) {
371 constexpr bool SuppressMangling = true; 400 constexpr bool SuppressMangling = true;
372 constexpr llvm::GlobalValue::LinkageTypes Linkage = 401 constexpr llvm::GlobalValue::LinkageTypes Linkage =
373 llvm::GlobalValue::ExternalLinkage; 402 llvm::GlobalValue::ExternalLinkage;
374 return create(Context, SuppressMangling, Linkage); 403 return create(VDL, SuppressMangling, Linkage);
375 } 404 }
376 405
377 const InitializerListType &getInitializers() const { return *Initializers; } 406 const InitializerListType &getInitializers() const { return Initializers; }
378 bool getIsConstant() const { return IsConstant; } 407 bool getIsConstant() const { return IsConstant; }
379 void setIsConstant(bool NewValue) { IsConstant = NewValue; } 408 void setIsConstant(bool NewValue) { IsConstant = NewValue; }
380 uint32_t getAlignment() const { return Alignment; } 409 uint32_t getAlignment() const { return Alignment; }
381 void setAlignment(uint32_t NewAlignment) { Alignment = NewAlignment; } 410 void setAlignment(uint32_t NewAlignment) { Alignment = NewAlignment; }
382 bool hasInitializer() const { return HasInitializer; } 411 bool hasInitializer() const { return HasInitializer; }
383 bool hasNonzeroInitializer() const { 412 bool hasNonzeroInitializer() const {
384 return !(Initializers->size() == 1 && 413 return !(Initializers.size() == 1 &&
385 llvm::isa<ZeroInitializer>((*Initializers)[0].get())); 414 llvm::isa<ZeroInitializer>(Initializers[0]));
386 } 415 }
387 416
388 /// Returns the number of bytes for the initializer of the global address. 417 /// Returns the number of bytes for the initializer of the global address.
389 SizeT getNumBytes() const { 418 SizeT getNumBytes() const {
390 SizeT Count = 0; 419 SizeT Count = 0;
391 for (const std::unique_ptr<Initializer> &Init : *Initializers) { 420 for (const auto *Init : Initializers) {
392 Count += Init->getNumBytes(); 421 Count += Init->getNumBytes();
393 } 422 }
394 return Count; 423 return Count;
395 } 424 }
396 425
397 /// Adds Initializer to the list of initializers. Takes ownership of the 426 /// Adds Initializer to the list of initializers. Takes ownership of the
398 /// initializer. 427 /// initializer.
399 void addInitializer(std::unique_ptr<Initializer> Initializer) { 428 void addInitializer(Initializer *Initializer) {
400 const bool OldSuppressMangling = getSuppressMangling(); 429 const bool OldSuppressMangling = getSuppressMangling();
401 Initializers->emplace_back(std::move(Initializer)); 430 Initializers.emplace_back(Initializer);
402 HasInitializer = true; 431 HasInitializer = true;
403 // The getSuppressMangling() logic depends on whether the global variable 432 // The getSuppressMangling() logic depends on whether the global variable
404 // has initializers. If its value changed as a result of adding an 433 // 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 434 // initializer, then make sure we haven't previously set the name based on
406 // faulty SuppressMangling logic. 435 // faulty SuppressMangling logic.
407 const bool SameMangling = (OldSuppressMangling == getSuppressMangling()); 436 const bool SameMangling = (OldSuppressMangling == getSuppressMangling());
408 (void)SameMangling; 437 (void)SameMangling;
409 assert(!Name.empty() || SameMangling); 438 assert(!Name.empty() || SameMangling);
410 } 439 }
411 440
(...skipping 12 matching lines...) Expand all
424 static bool classof(const GlobalDeclaration *Addr) { 453 static bool classof(const GlobalDeclaration *Addr) {
425 return Addr->getKind() == VariableDeclarationKind; 454 return Addr->getKind() == VariableDeclarationKind;
426 } 455 }
427 456
428 bool getSuppressMangling() const final { 457 bool getSuppressMangling() const final {
429 if (ForceSuppressMangling) 458 if (ForceSuppressMangling)
430 return true; 459 return true;
431 return isExternal() && !hasInitializer(); 460 return isExternal() && !hasInitializer();
432 } 461 }
433 462
434 void discardInitializers() { Initializers = nullptr; } 463 void discardInitializers() { Initializers.clear(); }
435 464
436 private: 465 private:
437 /// List of initializers for the declared variable. 466 /// List of initializers for the declared variable.
438 std::unique_ptr<InitializerListType> Initializers; 467 InitializerListType Initializers;
439 bool HasInitializer = false; 468 bool HasInitializer = false;
440 /// The alignment of the declared variable. 469 /// The alignment of the declared variable.
441 uint32_t Alignment = 0; 470 uint32_t Alignment = 0;
442 /// True if a declared (global) constant. 471 /// True if a declared (global) constant.
443 bool IsConstant = false; 472 bool IsConstant = false;
444 /// If set to true, force getSuppressMangling() to return true. 473 /// If set to true, force getSuppressMangling() to return true.
445 const bool ForceSuppressMangling; 474 const bool ForceSuppressMangling;
446 475
447 VariableDeclaration(llvm::GlobalValue::LinkageTypes Linkage, 476 VariableDeclaration(llvm::GlobalValue::LinkageTypes Linkage,
448 bool SuppressMangling) 477 bool SuppressMangling)
449 : GlobalDeclaration(VariableDeclarationKind, Linkage), 478 : GlobalDeclaration(VariableDeclarationKind, Linkage),
450 Initializers(new InitializerListType),
451 ForceSuppressMangling(SuppressMangling) {} 479 ForceSuppressMangling(SuppressMangling) {}
452 }; 480 };
453 481
454 template <class StreamType> 482 template <class StreamType>
455 inline StreamType &operator<<(StreamType &Stream, 483 inline StreamType &operator<<(StreamType &Stream,
456 const VariableDeclaration::Initializer &Init) { 484 const VariableDeclaration::Initializer &Init) {
457 Init.dump(Stream); 485 Init.dump(Stream);
458 return Stream; 486 return Stream;
459 } 487 }
460 488
461 template <class StreamType> 489 template <class StreamType>
462 inline StreamType &operator<<(StreamType &Stream, 490 inline StreamType &operator<<(StreamType &Stream,
463 const GlobalDeclaration &Addr) { 491 const GlobalDeclaration &Addr) {
464 Addr.dump(Stream); 492 Addr.dump(Stream);
465 return Stream; 493 return Stream;
466 } 494 }
467 495
468 } // end of namespace Ice 496 } // end of namespace Ice
469 497
470 #endif // SUBZERO_SRC_ICEGLOBALINITS_H 498 #endif // SUBZERO_SRC_ICEGLOBALINITS_H
OLDNEW
« no previous file with comments | « src/IceGlobalContext.cpp ('k') | src/IceGlobalInits.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698