1 // Copyright 2014 the V8 project authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef V8_BOOTSTRAPPER_H_ 6 #define V8_BOOTSTRAPPER_H_ 7 8 #include "src/factory.h" 9 10 namespace v8 { 11 namespace internal { 12 13 // A SourceCodeCache uses a FixedArray to store pairs of 14 // (OneByteString*, JSFunction*), mapping names of native code files 15 // (runtime.js, etc.) to precompiled functions. Instead of mapping 16 // names to functions it might make sense to let the JS2C tool 17 // generate an index for each native JS file. 18 class SourceCodeCache final BASE_EMBEDDED { 19 public: 20 explicit SourceCodeCache(Script::Type type): type_(type), cache_(NULL) { } 21 22 void Initialize(Isolate* isolate, bool create_heap_objects) { 23 cache_ = create_heap_objects ? isolate->heap()->empty_fixed_array() : NULL; 24 } 25 26 void Iterate(ObjectVisitor* v) { 27 v->VisitPointer(bit_cast<Object**, FixedArray**>(&cache_)); 28 } 29 30 bool Lookup(Vector<const char> name, Handle<SharedFunctionInfo>* handle) { 31 for (int i = 0; i < cache_->length(); i+=2) { 32 SeqOneByteString* str = SeqOneByteString::cast(cache_->get(i)); 33 if (str->IsUtf8EqualTo(name)) { 34 *handle = Handle<SharedFunctionInfo>( 35 SharedFunctionInfo::cast(cache_->get(i + 1))); 36 return true; 37 } 38 } 39 return false; 40 } 41 42 void Add(Vector<const char> name, Handle<SharedFunctionInfo> shared) { 43 Isolate* isolate = shared->GetIsolate(); 44 Factory* factory = isolate->factory(); 45 HandleScope scope(isolate); 46 int length = cache_->length(); 47 Handle<FixedArray> new_array = factory->NewFixedArray(length + 2, TENURED); 48 cache_->CopyTo(0, *new_array, 0, cache_->length()); 49 cache_ = *new_array; 50 Handle<String> str = 51 factory->NewStringFromAscii(name, TENURED).ToHandleChecked(); 52 DCHECK(!str.is_null()); 53 cache_->set(length, *str); 54 cache_->set(length + 1, *shared); 55 Script::cast(shared->script())->set_type(type_); 56 } 57 58 private: 59 Script::Type type_; 60 FixedArray* cache_; 61 DISALLOW_COPY_AND_ASSIGN(SourceCodeCache); 62 }; 63 64 enum ContextType { FULL_CONTEXT, THIN_CONTEXT, DEBUG_CONTEXT }; 65 66 // The Boostrapper is the public interface for creating a JavaScript global 67 // context. 68 class Bootstrapper final { 69 public: 70 static void InitializeOncePerProcess(); 71 static void TearDownExtensions(); 72 73 // Requires: Heap::SetUp has been called. 74 void Initialize(bool create_heap_objects); 75 void TearDown(); 76 77 // Creates a JavaScript Global Context with initial object graph. 78 // The returned value is a global handle casted to V8Environment*. 79 Handle<Context> CreateEnvironment( 80 MaybeHandle<JSGlobalProxy> maybe_global_proxy, 81 v8::Local<v8::ObjectTemplate> global_object_template, 82 v8::ExtensionConfiguration* extensions, 83 ContextType context_type = FULL_CONTEXT); 84 85 // Detach the environment from its outer global object. 86 void DetachGlobal(Handle<Context> env); 87 88 // Traverses the pointers for memory management. 89 void Iterate(ObjectVisitor* v); 90 91 // Accessor for the native scripts source code. 92 template <class Source> 93 Handle<String> SourceLookup(int index); 94 95 // Tells whether bootstrapping is active. 96 bool IsActive() const { return nesting_ != 0; } 97 98 // Support for thread preemption. 99 static int ArchiveSpacePerThread(); 100 char* ArchiveState(char* to); 101 char* RestoreState(char* from); 102 void FreeThreadResources(); 103 104 // Used for new context creation. 105 bool InstallExtensions(Handle<Context> native_context, 106 v8::ExtensionConfiguration* extensions); 107 108 SourceCodeCache* extensions_cache() { return &extensions_cache_; } 109 110 static bool CompileNative(Isolate* isolate, Vector<const char> name, 111 Handle<String> source, int argc, 112 Handle<Object> argv[]); 113 static bool CompileBuiltin(Isolate* isolate, int index); 114 static bool CompileExperimentalBuiltin(Isolate* isolate, int index); 115 static bool CompileExtraBuiltin(Isolate* isolate, int index); 116 static bool CompileExperimentalExtraBuiltin(Isolate* isolate, int index); 117 118 static void ExportFromRuntime(Isolate* isolate, Handle<JSObject> container); 119 static void ExportExperimentalFromRuntime(Isolate* isolate, 120 Handle<JSObject> container); 121 122 private: 123 Isolate* isolate_; 124 typedef int NestingCounterType; 125 NestingCounterType nesting_; 126 SourceCodeCache extensions_cache_; 127 128 friend class BootstrapperActive; 129 friend class Isolate; 130 friend class NativesExternalStringResource; 131 132 explicit Bootstrapper(Isolate* isolate); 133 134 static v8::Extension* free_buffer_extension_; 135 static v8::Extension* gc_extension_; 136 static v8::Extension* externalize_string_extension_; 137 static v8::Extension* statistics_extension_; 138 static v8::Extension* trigger_failure_extension_; 139 140 DISALLOW_COPY_AND_ASSIGN(Bootstrapper); 141 }; 142 143 144 class BootstrapperActive final BASE_EMBEDDED { 145 public: 146 explicit BootstrapperActive(Bootstrapper* bootstrapper) 147 : bootstrapper_(bootstrapper) { 148 ++bootstrapper_->nesting_; 149 } 150 151 ~BootstrapperActive() { 152 --bootstrapper_->nesting_; 153 } 154 155 private: 156 Bootstrapper* bootstrapper_; 157 158 DISALLOW_COPY_AND_ASSIGN(BootstrapperActive); 159 }; 160 161 162 class NativesExternalStringResource final 163 : public v8::String::ExternalOneByteStringResource { 164 public: 165 NativesExternalStringResource(const char* source, size_t length) 166 : data_(source), length_(length) {} 167 const char* data() const override { return data_; } 168 size_t length() const override { return length_; } 169 170 private: 171 const char* data_; 172 size_t length_; 173 }; 174 175 } // namespace internal 176 } // namespace v8 177 178 #endif // V8_BOOTSTRAPPER_H_ 179