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: SourceCodeCache(Script::Type type)20 explicit SourceCodeCache(Script::Type type): type_(type), cache_(NULL) { } 21 Initialize(Isolate * isolate,bool create_heap_objects)22 void Initialize(Isolate* isolate, bool create_heap_objects) { 23 cache_ = create_heap_objects ? isolate->heap()->empty_fixed_array() : NULL; 24 } 25 Iterate(ObjectVisitor * v)26 void Iterate(ObjectVisitor* v) { 27 v->VisitPointer(bit_cast<Object**, FixedArray**>(&cache_)); 28 } 29 Lookup(Vector<const char> name,Handle<SharedFunctionInfo> * handle)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 Add(Vector<const char> name,Handle<SharedFunctionInfo> shared)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 GlobalContextType { FULL_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, size_t context_snapshot_index, 83 v8::DeserializeInternalFieldsCallback internal_fields_deserializer, 84 GlobalContextType context_type = FULL_CONTEXT); 85 86 Handle<JSGlobalProxy> NewRemoteContext( 87 MaybeHandle<JSGlobalProxy> maybe_global_proxy, 88 v8::Local<v8::ObjectTemplate> global_object_template); 89 90 // Detach the environment from its outer global object. 91 void DetachGlobal(Handle<Context> env); 92 93 // Traverses the pointers for memory management. 94 void Iterate(ObjectVisitor* v); 95 96 // Accessor for the native scripts source code. 97 template <class Source> 98 Handle<String> SourceLookup(int index); 99 100 // Tells whether bootstrapping is active. IsActive()101 bool IsActive() const { return nesting_ != 0; } 102 103 // Support for thread preemption. 104 static int ArchiveSpacePerThread(); 105 char* ArchiveState(char* to); 106 char* RestoreState(char* from); 107 void FreeThreadResources(); 108 109 // Used for new context creation. 110 bool InstallExtensions(Handle<Context> native_context, 111 v8::ExtensionConfiguration* extensions); 112 extensions_cache()113 SourceCodeCache* extensions_cache() { return &extensions_cache_; } 114 115 static bool CompileNative(Isolate* isolate, Vector<const char> name, 116 Handle<String> source, int argc, 117 Handle<Object> argv[], NativesFlag natives_flag); 118 static bool CompileBuiltin(Isolate* isolate, int index); 119 static bool CompileExperimentalBuiltin(Isolate* isolate, int index); 120 static bool CompileExtraBuiltin(Isolate* isolate, int index); 121 static bool CompileExperimentalExtraBuiltin(Isolate* isolate, int index); 122 123 static void ExportFromRuntime(Isolate* isolate, Handle<JSObject> container); 124 125 private: 126 Isolate* isolate_; 127 typedef int NestingCounterType; 128 NestingCounterType nesting_; 129 SourceCodeCache extensions_cache_; 130 131 friend class BootstrapperActive; 132 friend class Isolate; 133 friend class NativesExternalStringResource; 134 135 explicit Bootstrapper(Isolate* isolate); 136 137 static v8::Extension* free_buffer_extension_; 138 static v8::Extension* gc_extension_; 139 static v8::Extension* externalize_string_extension_; 140 static v8::Extension* statistics_extension_; 141 static v8::Extension* trigger_failure_extension_; 142 static v8::Extension* ignition_statistics_extension_; 143 144 DISALLOW_COPY_AND_ASSIGN(Bootstrapper); 145 }; 146 147 148 class BootstrapperActive final BASE_EMBEDDED { 149 public: BootstrapperActive(Bootstrapper * bootstrapper)150 explicit BootstrapperActive(Bootstrapper* bootstrapper) 151 : bootstrapper_(bootstrapper) { 152 ++bootstrapper_->nesting_; 153 } 154 ~BootstrapperActive()155 ~BootstrapperActive() { 156 --bootstrapper_->nesting_; 157 } 158 159 private: 160 Bootstrapper* bootstrapper_; 161 162 DISALLOW_COPY_AND_ASSIGN(BootstrapperActive); 163 }; 164 165 166 class NativesExternalStringResource final 167 : public v8::String::ExternalOneByteStringResource { 168 public: NativesExternalStringResource(const char * source,size_t length)169 NativesExternalStringResource(const char* source, size_t length) 170 : data_(source), length_(length) {} data()171 const char* data() const override { return data_; } length()172 size_t length() const override { return length_; } 173 174 private: 175 const char* data_; 176 size_t length_; 177 }; 178 179 } // namespace internal 180 } // namespace v8 181 182 #endif // V8_BOOTSTRAPPER_H_ 183