11456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org// Copyright 2012 the V8 project authors. All rights reserved. 23484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org// Use of this source code is governed by a BSD-style license that can be 33484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org// found in the LICENSE file. 41456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org 51456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org// The LazyInstance<Type, Traits> class manages a single instance of Type, 61456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org// which will be lazily created on the first time it's accessed. This class is 71456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org// useful for places you would normally use a function-level static, but you 81456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org// need to have guaranteed thread-safety. The Type constructor will only ever 91456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org// be called once, even if two threads are racing to create the object. Get() 101456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org// and Pointer() will always return the same, completely initialized instance. 111456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org// 121456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org// LazyInstance is completely thread safe, assuming that you create it safely. 131456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org// The class was designed to be POD initialized, so it shouldn't require a 141456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org// static constructor. It really only makes sense to declare a LazyInstance as 151456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org// a global variable using the LAZY_INSTANCE_INITIALIZER initializer. 161456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org// 171456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org// LazyInstance is similar to Singleton, except it does not have the singleton 181456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org// property. You can have multiple LazyInstance's of the same type, and each 191456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org// will manage a unique instance. It also preallocates the space for Type, as 201456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org// to avoid allocating the Type instance on the heap. This may help with the 211456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org// performance of creating the instance, and reducing heap fragmentation. This 221456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org// requires that Type be a complete type so we can determine the size. See 231456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org// notes for advanced users below for more explanations. 241456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org// 251456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org// Example usage: 261456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org// static LazyInstance<MyClass>::type my_instance = LAZY_INSTANCE_INITIALIZER; 271456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org// void SomeMethod() { 281456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org// my_instance.Get().SomeMethod(); // MyClass::SomeMethod() 291456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org// 301456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org// MyClass* ptr = my_instance.Pointer(); 311456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org// ptr->DoDoDo(); // MyClass::DoDoDo 321456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org// } 331456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org// 341456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org// Additionally you can override the way your instance is constructed by 351456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org// providing your own trait: 361456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org// Example usage: 371456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org// struct MyCreateTrait { 381456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org// static void Construct(MyClass* allocated_ptr) { 391456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org// new (allocated_ptr) MyClass(/* extra parameters... */); 401456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org// } 411456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org// }; 421456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org// static LazyInstance<MyClass, MyCreateTrait>::type my_instance = 431456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org// LAZY_INSTANCE_INITIALIZER; 441456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org// 457d10be581a91ab5eefa1139ff0b86c64ac8f6e59fschneider@chromium.org// WARNINGS: 469fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org// - This implementation of LazyInstance IS THREAD-SAFE by default. See 479fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org// SingleThreadInitOnceTrait if you don't care about thread safety. 487d10be581a91ab5eefa1139ff0b86c64ac8f6e59fschneider@chromium.org// - Lazy initialization comes with a cost. Make sure that you don't use it on 497d10be581a91ab5eefa1139ff0b86c64ac8f6e59fschneider@chromium.org// critical path. Consider adding your initialization code to a function 507d10be581a91ab5eefa1139ff0b86c64ac8f6e59fschneider@chromium.org// which is explicitly called once. 518c0a43f09f145d9fc6f969d559873018176eeb6adanno@chromium.org// 521456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org// Notes for advanced users: 531456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org// LazyInstance can actually be used in two different ways: 541456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org// 551456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org// - "Static mode" which is the default mode since it is the most efficient 561456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org// (no extra heap allocation). In this mode, the instance is statically 571456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org// allocated (stored in the global data section at compile time). 581456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org// The macro LAZY_STATIC_INSTANCE_INITIALIZER (= LAZY_INSTANCE_INITIALIZER) 591456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org// must be used to initialize static lazy instances. 601456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org// 611456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org// - "Dynamic mode". In this mode, the instance is dynamically allocated and 621456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org// constructed (using new) by default. This mode is useful if you have to 631456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org// deal with some code already allocating the instance for you (e.g. 641456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org// OS::Mutex() which returns a new private OS-dependent subclass of Mutex). 651456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org// The macro LAZY_DYNAMIC_INSTANCE_INITIALIZER must be used to initialize 661456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org// dynamic lazy instances. 671456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org 681e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org#ifndef V8_BASE_LAZY_INSTANCE_H_ 691e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org#define V8_BASE_LAZY_INSTANCE_H_ 701456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org 71196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/base/macros.h" 721e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org#include "src/base/once.h" 731456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org 741456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.orgnamespace v8 { 751e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.orgnamespace base { 761456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org 771e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org#define LAZY_STATIC_INSTANCE_INITIALIZER { V8_ONCE_INIT, { {} } } 781456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org#define LAZY_DYNAMIC_INSTANCE_INITIALIZER { V8_ONCE_INIT, 0 } 791456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org 801456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org// Default to static mode. 811456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org#define LAZY_INSTANCE_INITIALIZER LAZY_STATIC_INSTANCE_INITIALIZER 821456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org 831456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org 841456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.orgtemplate <typename T> 851456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.orgstruct LeakyInstanceTrait { 861456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org static void Destroy(T* /* instance */) {} 871456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org}; 881456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org 891456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org 901456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org// Traits that define how an instance is allocated and accessed. 911456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org 927d10be581a91ab5eefa1139ff0b86c64ac8f6e59fschneider@chromium.org 931456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.orgtemplate <typename T> 941456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.orgstruct StaticallyAllocatedInstanceTrait { 951e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org // 16-byte alignment fallback to be on the safe side here. 961e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org struct V8_ALIGNAS(T, 16) StorageType { 971e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org char x[sizeof(T)]; 981e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org }; 991e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org 1001e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org STATIC_ASSERT(V8_ALIGNOF(StorageType) >= V8_ALIGNOF(T)); 1011456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org 1021456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org static T* MutableInstance(StorageType* storage) { 1031456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org return reinterpret_cast<T*>(storage); 1041456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org } 1051456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org 1061456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org template <typename ConstructTrait> 1071456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org static void InitStorageUsingTrait(StorageType* storage) { 1081456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org ConstructTrait::Construct(MutableInstance(storage)); 1091456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org } 1101456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org}; 1111456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org 1121456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org 1131456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.orgtemplate <typename T> 1141456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.orgstruct DynamicallyAllocatedInstanceTrait { 1151456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org typedef T* StorageType; 1161456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org 1171456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org static T* MutableInstance(StorageType* storage) { 1181456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org return *storage; 1191456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org } 1201456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org 1211456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org template <typename CreateTrait> 1221456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org static void InitStorageUsingTrait(StorageType* storage) { 1231456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org *storage = CreateTrait::Create(); 1241456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org } 1251456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org}; 1261456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org 1271456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org 1281456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.orgtemplate <typename T> 1291456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.orgstruct DefaultConstructTrait { 1301456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org // Constructs the provided object which was already allocated. 1311456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org static void Construct(T* allocated_ptr) { 1321456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org new(allocated_ptr) T(); 1331456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org } 1341456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org}; 1351456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org 1361456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org 1371456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.orgtemplate <typename T> 1381456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.orgstruct DefaultCreateTrait { 1391456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org static T* Create() { 1401456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org return new T(); 1411456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org } 1421456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org}; 1431456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org 1441456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org 1458c0a43f09f145d9fc6f969d559873018176eeb6adanno@chromium.orgstruct ThreadSafeInitOnceTrait { 1468c0a43f09f145d9fc6f969d559873018176eeb6adanno@chromium.org template <typename Function, typename Storage> 1478c0a43f09f145d9fc6f969d559873018176eeb6adanno@chromium.org static void Init(OnceType* once, Function function, Storage storage) { 1488c0a43f09f145d9fc6f969d559873018176eeb6adanno@chromium.org CallOnce(once, function, storage); 1498c0a43f09f145d9fc6f969d559873018176eeb6adanno@chromium.org } 1508c0a43f09f145d9fc6f969d559873018176eeb6adanno@chromium.org}; 1518c0a43f09f145d9fc6f969d559873018176eeb6adanno@chromium.org 1528c0a43f09f145d9fc6f969d559873018176eeb6adanno@chromium.org 1538c0a43f09f145d9fc6f969d559873018176eeb6adanno@chromium.org// Initialization trait for users who don't care about thread-safety. 1548c0a43f09f145d9fc6f969d559873018176eeb6adanno@chromium.orgstruct SingleThreadInitOnceTrait { 1558c0a43f09f145d9fc6f969d559873018176eeb6adanno@chromium.org template <typename Function, typename Storage> 1568c0a43f09f145d9fc6f969d559873018176eeb6adanno@chromium.org static void Init(OnceType* once, Function function, Storage storage) { 1578c0a43f09f145d9fc6f969d559873018176eeb6adanno@chromium.org if (*once == ONCE_STATE_UNINITIALIZED) { 1588c0a43f09f145d9fc6f969d559873018176eeb6adanno@chromium.org function(storage); 1598c0a43f09f145d9fc6f969d559873018176eeb6adanno@chromium.org *once = ONCE_STATE_DONE; 1608c0a43f09f145d9fc6f969d559873018176eeb6adanno@chromium.org } 1618c0a43f09f145d9fc6f969d559873018176eeb6adanno@chromium.org } 1628c0a43f09f145d9fc6f969d559873018176eeb6adanno@chromium.org}; 1638c0a43f09f145d9fc6f969d559873018176eeb6adanno@chromium.org 1648c0a43f09f145d9fc6f969d559873018176eeb6adanno@chromium.org 1651456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org// TODO(pliard): Handle instances destruction (using global destructors). 1661456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.orgtemplate <typename T, typename AllocationTrait, typename CreateTrait, 1678c0a43f09f145d9fc6f969d559873018176eeb6adanno@chromium.org typename InitOnceTrait, typename DestroyTrait /* not used yet. */> 1681456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.orgstruct LazyInstanceImpl { 1691456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org public: 1701456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org typedef typename AllocationTrait::StorageType StorageType; 1711456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org 1721456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org private: 1731456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org static void InitInstance(StorageType* storage) { 1741456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org AllocationTrait::template InitStorageUsingTrait<CreateTrait>(storage); 1751456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org } 1761456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org 1771456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org void Init() const { 1788c0a43f09f145d9fc6f969d559873018176eeb6adanno@chromium.org InitOnceTrait::Init( 1798c0a43f09f145d9fc6f969d559873018176eeb6adanno@chromium.org &once_, 1808c0a43f09f145d9fc6f969d559873018176eeb6adanno@chromium.org // Casts to void* are needed here to avoid breaking strict aliasing 1818c0a43f09f145d9fc6f969d559873018176eeb6adanno@chromium.org // rules. 1828c0a43f09f145d9fc6f969d559873018176eeb6adanno@chromium.org reinterpret_cast<void(*)(void*)>(&InitInstance), // NOLINT 1838c0a43f09f145d9fc6f969d559873018176eeb6adanno@chromium.org reinterpret_cast<void*>(&storage_)); 1841456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org } 1851456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org 1861456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org public: 1871456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org T* Pointer() { 1881456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org Init(); 1891456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org return AllocationTrait::MutableInstance(&storage_); 1901456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org } 1911456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org 1921456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org const T& Get() const { 1931456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org Init(); 1941456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org return *AllocationTrait::MutableInstance(&storage_); 1951456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org } 1961456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org 1971456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org mutable OnceType once_; 1981456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org // Note that the previous field, OnceType, is an AtomicWord which guarantees 1997d10be581a91ab5eefa1139ff0b86c64ac8f6e59fschneider@chromium.org // 4-byte alignment of the storage field below. If compiling with GCC (>4.2), 2007d10be581a91ab5eefa1139ff0b86c64ac8f6e59fschneider@chromium.org // the LAZY_ALIGN macro above will guarantee correctness for any alignment. 2011456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org mutable StorageType storage_; 2021456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org}; 2031456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org 2041456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org 2051456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.orgtemplate <typename T, 2061456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org typename CreateTrait = DefaultConstructTrait<T>, 2079fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org typename InitOnceTrait = ThreadSafeInitOnceTrait, 2081456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org typename DestroyTrait = LeakyInstanceTrait<T> > 2091456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.orgstruct LazyStaticInstance { 2108c0a43f09f145d9fc6f969d559873018176eeb6adanno@chromium.org typedef LazyInstanceImpl<T, StaticallyAllocatedInstanceTrait<T>, 2118c0a43f09f145d9fc6f969d559873018176eeb6adanno@chromium.org CreateTrait, InitOnceTrait, DestroyTrait> type; 2121456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org}; 2131456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org 2141456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org 2151456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.orgtemplate <typename T, 2161456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org typename CreateTrait = DefaultConstructTrait<T>, 2179fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org typename InitOnceTrait = ThreadSafeInitOnceTrait, 2181456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org typename DestroyTrait = LeakyInstanceTrait<T> > 2191456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.orgstruct LazyInstance { 2201456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org // A LazyInstance is a LazyStaticInstance. 2218c0a43f09f145d9fc6f969d559873018176eeb6adanno@chromium.org typedef typename LazyStaticInstance<T, CreateTrait, InitOnceTrait, 2228c0a43f09f145d9fc6f969d559873018176eeb6adanno@chromium.org DestroyTrait>::type type; 2231456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org}; 2241456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org 2251456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org 2261456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.orgtemplate <typename T, 227fb0463312815affb1f0e9d5e351b7f9a3422e3a2svenpanne@chromium.org typename CreateTrait = DefaultCreateTrait<T>, 2289fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org typename InitOnceTrait = ThreadSafeInitOnceTrait, 2291456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org typename DestroyTrait = LeakyInstanceTrait<T> > 2301456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.orgstruct LazyDynamicInstance { 2318c0a43f09f145d9fc6f969d559873018176eeb6adanno@chromium.org typedef LazyInstanceImpl<T, DynamicallyAllocatedInstanceTrait<T>, 2328c0a43f09f145d9fc6f969d559873018176eeb6adanno@chromium.org CreateTrait, InitOnceTrait, DestroyTrait> type; 2331456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org}; 2341456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org 2351e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org} } // namespace v8::base 2361456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org 2371e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org#endif // V8_BASE_LAZY_INSTANCE_H_ 238