13ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// Copyright 2012 the V8 project authors. All rights reserved. 23ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// Redistribution and use in source and binary forms, with or without 33ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// modification, are permitted provided that the following conditions are 43ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// met: 53ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// 63ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// * Redistributions of source code must retain the above copyright 73ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// notice, this list of conditions and the following disclaimer. 83ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// * Redistributions in binary form must reproduce the above 93ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// copyright notice, this list of conditions and the following 103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// disclaimer in the documentation and/or other materials provided 113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// with the distribution. 123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// * Neither the name of Google Inc. nor the names of its 133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// contributors may be used to endorse or promote products derived 143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// from this software without specific prior written permission. 153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// 163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// The LazyInstance<Type, Traits> class manages a single instance of Type, 293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// which will be lazily created on the first time it's accessed. This class is 303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// useful for places you would normally use a function-level static, but you 313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// need to have guaranteed thread-safety. The Type constructor will only ever 323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// be called once, even if two threads are racing to create the object. Get() 333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// and Pointer() will always return the same, completely initialized instance. 343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// 353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// LazyInstance is completely thread safe, assuming that you create it safely. 363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// The class was designed to be POD initialized, so it shouldn't require a 373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// static constructor. It really only makes sense to declare a LazyInstance as 383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// a global variable using the LAZY_INSTANCE_INITIALIZER initializer. 393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// 403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// LazyInstance is similar to Singleton, except it does not have the singleton 413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// property. You can have multiple LazyInstance's of the same type, and each 423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// will manage a unique instance. It also preallocates the space for Type, as 433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// to avoid allocating the Type instance on the heap. This may help with the 443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// performance of creating the instance, and reducing heap fragmentation. This 453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// requires that Type be a complete type so we can determine the size. See 463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// notes for advanced users below for more explanations. 473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// 483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// Example usage: 493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// static LazyInstance<MyClass>::type my_instance = LAZY_INSTANCE_INITIALIZER; 503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// void SomeMethod() { 513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// my_instance.Get().SomeMethod(); // MyClass::SomeMethod() 523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// 533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// MyClass* ptr = my_instance.Pointer(); 543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// ptr->DoDoDo(); // MyClass::DoDoDo 553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// } 563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// 573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// Additionally you can override the way your instance is constructed by 583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// providing your own trait: 593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// Example usage: 603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// struct MyCreateTrait { 613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// static void Construct(MyClass* allocated_ptr) { 623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// new (allocated_ptr) MyClass(/* extra parameters... */); 633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// } 643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// }; 653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// static LazyInstance<MyClass, MyCreateTrait>::type my_instance = 663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// LAZY_INSTANCE_INITIALIZER; 673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// 683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// WARNING: This implementation of LazyInstance is NOT thread-safe by default. 693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// See ThreadSafeInitOnceTrait declared below for that. 703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// 713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// Notes for advanced users: 723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// LazyInstance can actually be used in two different ways: 733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// 743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// - "Static mode" which is the default mode since it is the most efficient 753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// (no extra heap allocation). In this mode, the instance is statically 763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// allocated (stored in the global data section at compile time). 773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// The macro LAZY_STATIC_INSTANCE_INITIALIZER (= LAZY_INSTANCE_INITIALIZER) 783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// must be used to initialize static lazy instances. 793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// 803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// - "Dynamic mode". In this mode, the instance is dynamically allocated and 813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// constructed (using new) by default. This mode is useful if you have to 823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// deal with some code already allocating the instance for you (e.g. 833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// OS::Mutex() which returns a new private OS-dependent subclass of Mutex). 843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// The macro LAZY_DYNAMIC_INSTANCE_INITIALIZER must be used to initialize 853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// dynamic lazy instances. 863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#ifndef V8_LAZY_INSTANCE_H_ 883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#define V8_LAZY_INSTANCE_H_ 893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#include "once.h" 913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochnamespace v8 { 933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochnamespace internal { 943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#define LAZY_STATIC_INSTANCE_INITIALIZER { V8_ONCE_INIT, {} } 963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#define LAZY_DYNAMIC_INSTANCE_INITIALIZER { V8_ONCE_INIT, 0 } 973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// Default to static mode. 993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#define LAZY_INSTANCE_INITIALIZER LAZY_STATIC_INSTANCE_INITIALIZER 1003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 1013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 1023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochtemplate <typename T> 1033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochstruct LeakyInstanceTrait { 1043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch static void Destroy(T* /* instance */) {} 1053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}; 1063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 1073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 1083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// Traits that define how an instance is allocated and accessed. 1093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 1103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// TODO(kalmard): __alignof__ is only defined for GCC > 4.2. Fix alignment issue 1113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// on MIPS with other compilers. 1123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#if defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ > 2)) 1133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#define LAZY_ALIGN(x) __attribute__((aligned(__alignof__(x)))) 1143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#else 1153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#define LAZY_ALIGN(x) 1163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#endif 1173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 1183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochtemplate <typename T> 1193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochstruct StaticallyAllocatedInstanceTrait { 1203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch typedef char StorageType[sizeof(T)] LAZY_ALIGN(T); 1213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 1223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch static T* MutableInstance(StorageType* storage) { 1233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return reinterpret_cast<T*>(storage); 1243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 1253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 1263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch template <typename ConstructTrait> 1273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch static void InitStorageUsingTrait(StorageType* storage) { 1283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ConstructTrait::Construct(MutableInstance(storage)); 1293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 1303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}; 1313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 1323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#undef LAZY_ALIGN 1333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 1343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 1353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochtemplate <typename T> 1363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochstruct DynamicallyAllocatedInstanceTrait { 1373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch typedef T* StorageType; 1383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 1393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch static T* MutableInstance(StorageType* storage) { 1403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return *storage; 1413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 1423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 1433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch template <typename CreateTrait> 1443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch static void InitStorageUsingTrait(StorageType* storage) { 1453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch *storage = CreateTrait::Create(); 1463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 1473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}; 1483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 1493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 1503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochtemplate <typename T> 1513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochstruct DefaultConstructTrait { 1523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Constructs the provided object which was already allocated. 1533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch static void Construct(T* allocated_ptr) { 1543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch new(allocated_ptr) T(); 1553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 1563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}; 1573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 1583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 1593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochtemplate <typename T> 1603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochstruct DefaultCreateTrait { 1613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch static T* Create() { 1623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return new T(); 1633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 1643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}; 1653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 1663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 1673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochstruct ThreadSafeInitOnceTrait { 1683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch template <typename Function, typename Storage> 1693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch static void Init(OnceType* once, Function function, Storage storage) { 1703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CallOnce(once, function, storage); 1713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 1723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}; 1733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 1743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 1753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// Initialization trait for users who don't care about thread-safety. 1763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochstruct SingleThreadInitOnceTrait { 1773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch template <typename Function, typename Storage> 1783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch static void Init(OnceType* once, Function function, Storage storage) { 1793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (*once == ONCE_STATE_UNINITIALIZED) { 1803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch function(storage); 1813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch *once = ONCE_STATE_DONE; 1823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 1833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 1843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}; 1853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 1863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 1873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// TODO(pliard): Handle instances destruction (using global destructors). 1883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochtemplate <typename T, typename AllocationTrait, typename CreateTrait, 1893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch typename InitOnceTrait, typename DestroyTrait /* not used yet. */> 1903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochstruct LazyInstanceImpl { 1913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch public: 1923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch typedef typename AllocationTrait::StorageType StorageType; 1933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 1943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch private: 1953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch static void InitInstance(StorageType* storage) { 1963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch AllocationTrait::template InitStorageUsingTrait<CreateTrait>(storage); 1973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 1983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 1993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch void Init() const { 2003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch InitOnceTrait::Init( 2013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch &once_, 2023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Casts to void* are needed here to avoid breaking strict aliasing 2033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // rules. 2043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch reinterpret_cast<void(*)(void*)>(&InitInstance), // NOLINT 2053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch reinterpret_cast<void*>(&storage_)); 2063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 2073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 2083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch public: 2093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch T* Pointer() { 2103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Init(); 2113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return AllocationTrait::MutableInstance(&storage_); 2123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 2133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 2143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch const T& Get() const { 2153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Init(); 2163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return *AllocationTrait::MutableInstance(&storage_); 2173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 2183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 2193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch mutable OnceType once_; 2203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Note that the previous field, OnceType, is an AtomicWord which guarantees 2213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // 4-byte alignment of the storage field below. If compiling with GCC (>4.2), 2223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // the LAZY_ALIGN macro above will guarantee correctness for any alignment. 2233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch mutable StorageType storage_; 2243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}; 2253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 2263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 2273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochtemplate <typename T, 2283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch typename CreateTrait = DefaultConstructTrait<T>, 2293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch typename InitOnceTrait = SingleThreadInitOnceTrait, 2303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch typename DestroyTrait = LeakyInstanceTrait<T> > 2313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochstruct LazyStaticInstance { 2323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch typedef LazyInstanceImpl<T, StaticallyAllocatedInstanceTrait<T>, 2333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CreateTrait, InitOnceTrait, DestroyTrait> type; 2343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}; 2353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 2363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 2373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochtemplate <typename T, 2383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch typename CreateTrait = DefaultConstructTrait<T>, 2393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch typename InitOnceTrait = SingleThreadInitOnceTrait, 2403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch typename DestroyTrait = LeakyInstanceTrait<T> > 2413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochstruct LazyInstance { 2423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // A LazyInstance is a LazyStaticInstance. 2433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch typedef typename LazyStaticInstance<T, CreateTrait, InitOnceTrait, 2443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch DestroyTrait>::type type; 2453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}; 2463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 2473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 2483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochtemplate <typename T, 2493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch typename CreateTrait = DefaultConstructTrait<T>, 2503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch typename InitOnceTrait = SingleThreadInitOnceTrait, 2513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch typename DestroyTrait = LeakyInstanceTrait<T> > 2523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochstruct LazyDynamicInstance { 2533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch typedef LazyInstanceImpl<T, DynamicallyAllocatedInstanceTrait<T>, 2543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CreateTrait, InitOnceTrait, DestroyTrait> type; 2553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}; 2563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 2573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} } // namespace v8::internal 2583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 2593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#endif // V8_LAZY_INSTANCE_H_ 260