13ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// Copyright 2012 the V8 project authors. All rights reserved. 2b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Use of this source code is governed by a BSD-style license that can be 3b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// found in the LICENSE file. 43ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 53ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// The LazyInstance<Type, Traits> class manages a single instance of Type, 63ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// which will be lazily created on the first time it's accessed. This class is 73ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// useful for places you would normally use a function-level static, but you 83ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// need to have guaranteed thread-safety. The Type constructor will only ever 93ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// be called once, even if two threads are racing to create the object. Get() 103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// and Pointer() will always return the same, completely initialized instance. 113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// 123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// LazyInstance is completely thread safe, assuming that you create it safely. 133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// The class was designed to be POD initialized, so it shouldn't require a 143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// static constructor. It really only makes sense to declare a LazyInstance as 153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// a global variable using the LAZY_INSTANCE_INITIALIZER initializer. 163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// 173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// LazyInstance is similar to Singleton, except it does not have the singleton 183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// property. You can have multiple LazyInstance's of the same type, and each 193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// will manage a unique instance. It also preallocates the space for Type, as 203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// to avoid allocating the Type instance on the heap. This may help with the 213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// performance of creating the instance, and reducing heap fragmentation. This 223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// requires that Type be a complete type so we can determine the size. See 233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// notes for advanced users below for more explanations. 243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// 253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// Example usage: 263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// static LazyInstance<MyClass>::type my_instance = LAZY_INSTANCE_INITIALIZER; 273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// void SomeMethod() { 283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// my_instance.Get().SomeMethod(); // MyClass::SomeMethod() 293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// 303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// MyClass* ptr = my_instance.Pointer(); 313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// ptr->DoDoDo(); // MyClass::DoDoDo 323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// } 333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// 343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// Additionally you can override the way your instance is constructed by 353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// providing your own trait: 363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// Example usage: 373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// struct MyCreateTrait { 383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// static void Construct(MyClass* allocated_ptr) { 393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// new (allocated_ptr) MyClass(/* extra parameters... */); 403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// } 413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// }; 423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// static LazyInstance<MyClass, MyCreateTrait>::type my_instance = 433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// LAZY_INSTANCE_INITIALIZER; 443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// 45b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// WARNINGS: 46b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// - This implementation of LazyInstance IS THREAD-SAFE by default. See 47b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// SingleThreadInitOnceTrait if you don't care about thread safety. 48b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// - Lazy initialization comes with a cost. Make sure that you don't use it on 49b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// critical path. Consider adding your initialization code to a function 50b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// which is explicitly called once. 513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// 523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// Notes for advanced users: 533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// LazyInstance can actually be used in two different ways: 543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// 553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// - "Static mode" which is the default mode since it is the most efficient 563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// (no extra heap allocation). In this mode, the instance is statically 573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// allocated (stored in the global data section at compile time). 583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// The macro LAZY_STATIC_INSTANCE_INITIALIZER (= LAZY_INSTANCE_INITIALIZER) 593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// must be used to initialize static lazy instances. 603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// 613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// - "Dynamic mode". In this mode, the instance is dynamically allocated and 623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// constructed (using new) by default. This mode is useful if you have to 633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// deal with some code already allocating the instance for you (e.g. 643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// OS::Mutex() which returns a new private OS-dependent subclass of Mutex). 653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// The macro LAZY_DYNAMIC_INSTANCE_INITIALIZER must be used to initialize 663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// dynamic lazy instances. 673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 68b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#ifndef V8_BASE_LAZY_INSTANCE_H_ 69b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#define V8_BASE_LAZY_INSTANCE_H_ 703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 71b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/base/macros.h" 72b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/base/once.h" 733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochnamespace v8 { 75b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochnamespace base { 763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 77b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#define LAZY_STATIC_INSTANCE_INITIALIZER { V8_ONCE_INIT, { {} } } 783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#define LAZY_DYNAMIC_INSTANCE_INITIALIZER { V8_ONCE_INIT, 0 } 793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// Default to static mode. 813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#define LAZY_INSTANCE_INITIALIZER LAZY_STATIC_INSTANCE_INITIALIZER 823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochtemplate <typename T> 853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochstruct LeakyInstanceTrait { 863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch static void Destroy(T* /* instance */) {} 873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}; 883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// Traits that define how an instance is allocated and accessed. 913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochtemplate <typename T> 943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochstruct StaticallyAllocatedInstanceTrait { 95b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // 16-byte alignment fallback to be on the safe side here. 96b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch struct V8_ALIGNAS(T, 16) StorageType { 97b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch char x[sizeof(T)]; 98b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch }; 99b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 100b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch STATIC_ASSERT(V8_ALIGNOF(StorageType) >= V8_ALIGNOF(T)); 1013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 1023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch static T* MutableInstance(StorageType* storage) { 1033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return reinterpret_cast<T*>(storage); 1043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 1053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 1063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch template <typename ConstructTrait> 1073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch static void InitStorageUsingTrait(StorageType* storage) { 1083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ConstructTrait::Construct(MutableInstance(storage)); 1093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 1103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}; 1113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 1123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 1133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochtemplate <typename T> 1143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochstruct DynamicallyAllocatedInstanceTrait { 1153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch typedef T* StorageType; 1163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 1173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch static T* MutableInstance(StorageType* storage) { 1183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return *storage; 1193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 1203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 1213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch template <typename CreateTrait> 1223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch static void InitStorageUsingTrait(StorageType* storage) { 1233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch *storage = CreateTrait::Create(); 1243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 1253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}; 1263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 1273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 1283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochtemplate <typename T> 1293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochstruct DefaultConstructTrait { 1303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Constructs the provided object which was already allocated. 1313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch static void Construct(T* allocated_ptr) { 1323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch new(allocated_ptr) T(); 1333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 1343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}; 1353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 1363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 1373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochtemplate <typename T> 1383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochstruct DefaultCreateTrait { 1393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch static T* Create() { 1403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return new T(); 1413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 1423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}; 1433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 1443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 1453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochstruct ThreadSafeInitOnceTrait { 1463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch template <typename Function, typename Storage> 1473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch static void Init(OnceType* once, Function function, Storage storage) { 1483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CallOnce(once, function, storage); 1493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 1503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}; 1513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 1523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 1533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// Initialization trait for users who don't care about thread-safety. 1543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochstruct SingleThreadInitOnceTrait { 1553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch template <typename Function, typename Storage> 1563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch static void Init(OnceType* once, Function function, Storage storage) { 1573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (*once == ONCE_STATE_UNINITIALIZED) { 1583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch function(storage); 1593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch *once = ONCE_STATE_DONE; 1603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 1613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 1623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}; 1633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 1643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 1653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// TODO(pliard): Handle instances destruction (using global destructors). 1663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochtemplate <typename T, typename AllocationTrait, typename CreateTrait, 1673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch typename InitOnceTrait, typename DestroyTrait /* not used yet. */> 1683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochstruct LazyInstanceImpl { 1693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch public: 1703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch typedef typename AllocationTrait::StorageType StorageType; 1713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 1723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch private: 1733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch static void InitInstance(StorageType* storage) { 1743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch AllocationTrait::template InitStorageUsingTrait<CreateTrait>(storage); 1753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 1763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 1773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch void Init() const { 1783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch InitOnceTrait::Init( 1793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch &once_, 1803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Casts to void* are needed here to avoid breaking strict aliasing 1813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // rules. 1823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch reinterpret_cast<void(*)(void*)>(&InitInstance), // NOLINT 1833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch reinterpret_cast<void*>(&storage_)); 1843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 1853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 1863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch public: 1873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch T* Pointer() { 1883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Init(); 1893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return AllocationTrait::MutableInstance(&storage_); 1903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 1913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 1923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch const T& Get() const { 1933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Init(); 1943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return *AllocationTrait::MutableInstance(&storage_); 1953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 1963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 1973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch mutable OnceType once_; 1983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Note that the previous field, OnceType, is an AtomicWord which guarantees 1993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // 4-byte alignment of the storage field below. If compiling with GCC (>4.2), 2003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // the LAZY_ALIGN macro above will guarantee correctness for any alignment. 2013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch mutable StorageType storage_; 2023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}; 2033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 2043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 2053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochtemplate <typename T, 2063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch typename CreateTrait = DefaultConstructTrait<T>, 207b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch typename InitOnceTrait = ThreadSafeInitOnceTrait, 2083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch typename DestroyTrait = LeakyInstanceTrait<T> > 2093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochstruct LazyStaticInstance { 2103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch typedef LazyInstanceImpl<T, StaticallyAllocatedInstanceTrait<T>, 2113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CreateTrait, InitOnceTrait, DestroyTrait> type; 2123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}; 2133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 2143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 2153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochtemplate <typename T, 2163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch typename CreateTrait = DefaultConstructTrait<T>, 217b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch typename InitOnceTrait = ThreadSafeInitOnceTrait, 2183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch typename DestroyTrait = LeakyInstanceTrait<T> > 2193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochstruct LazyInstance { 2203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // A LazyInstance is a LazyStaticInstance. 2213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch typedef typename LazyStaticInstance<T, CreateTrait, InitOnceTrait, 2223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch DestroyTrait>::type type; 2233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}; 2243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 2253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 2263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochtemplate <typename T, 227b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch typename CreateTrait = DefaultCreateTrait<T>, 228b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch typename InitOnceTrait = ThreadSafeInitOnceTrait, 2293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch typename DestroyTrait = LeakyInstanceTrait<T> > 2303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochstruct LazyDynamicInstance { 2313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch typedef LazyInstanceImpl<T, DynamicallyAllocatedInstanceTrait<T>, 2323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CreateTrait, InitOnceTrait, DestroyTrait> type; 2333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}; 2343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 235014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} // namespace base 236014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} // namespace v8 2373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 238b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif // V8_BASE_LAZY_INSTANCE_H_ 239