Ben Murdoch | b8a8cc1 | 2014-11-26 15:28:44 +0000 | [diff] [blame] | 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. |
Steve Block | a7e24c1 | 2009-10-30 11:49:00 +0000 | [diff] [blame] | 4 | |
| 5 | #ifndef V8_BOOTSTRAPPER_H_ |
| 6 | #define V8_BOOTSTRAPPER_H_ |
| 7 | |
Ben Murdoch | b8a8cc1 | 2014-11-26 15:28:44 +0000 | [diff] [blame] | 8 | #include "src/factory.h" |
Ben Murdoch | 257744e | 2011-11-30 15:57:28 +0000 | [diff] [blame] | 9 | |
Steve Block | a7e24c1 | 2009-10-30 11:49:00 +0000 | [diff] [blame] | 10 | namespace v8 { |
| 11 | namespace internal { |
| 12 | |
Steve Block | 44f0eee | 2011-05-26 01:26:41 +0100 | [diff] [blame] | 13 | // A SourceCodeCache uses a FixedArray to store pairs of |
Ben Murdoch | b8a8cc1 | 2014-11-26 15:28:44 +0000 | [diff] [blame] | 14 | // (OneByteString*, JSFunction*), mapping names of native code files |
Steve Block | 44f0eee | 2011-05-26 01:26:41 +0100 | [diff] [blame] | 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. |
Ben Murdoch | 4a90d5f | 2016-03-22 12:00:34 +0000 | [diff] [blame] | 18 | class SourceCodeCache final BASE_EMBEDDED { |
Andrei Popescu | 3100271 | 2010-02-23 13:46:05 +0000 | [diff] [blame] | 19 | public: |
Steve Block | 44f0eee | 2011-05-26 01:26:41 +0100 | [diff] [blame] | 20 | explicit SourceCodeCache(Script::Type type): type_(type), cache_(NULL) { } |
Andrei Popescu | 3100271 | 2010-02-23 13:46:05 +0000 | [diff] [blame] | 21 | |
Ben Murdoch | b8a8cc1 | 2014-11-26 15:28:44 +0000 | [diff] [blame] | 22 | void Initialize(Isolate* isolate, bool create_heap_objects) { |
| 23 | cache_ = create_heap_objects ? isolate->heap()->empty_fixed_array() : NULL; |
Steve Block | 44f0eee | 2011-05-26 01:26:41 +0100 | [diff] [blame] | 24 | } |
| 25 | |
| 26 | void Iterate(ObjectVisitor* v) { |
Ben Murdoch | b8a8cc1 | 2014-11-26 15:28:44 +0000 | [diff] [blame] | 27 | v->VisitPointer(bit_cast<Object**, FixedArray**>(&cache_)); |
Steve Block | 44f0eee | 2011-05-26 01:26:41 +0100 | [diff] [blame] | 28 | } |
| 29 | |
| 30 | bool Lookup(Vector<const char> name, Handle<SharedFunctionInfo>* handle) { |
| 31 | for (int i = 0; i < cache_->length(); i+=2) { |
Ben Murdoch | b8a8cc1 | 2014-11-26 15:28:44 +0000 | [diff] [blame] | 32 | SeqOneByteString* str = SeqOneByteString::cast(cache_->get(i)); |
| 33 | if (str->IsUtf8EqualTo(name)) { |
Steve Block | 44f0eee | 2011-05-26 01:26:41 +0100 | [diff] [blame] | 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) { |
Ben Murdoch | b8a8cc1 | 2014-11-26 15:28:44 +0000 | [diff] [blame] | 43 | Isolate* isolate = shared->GetIsolate(); |
| 44 | Factory* factory = isolate->factory(); |
| 45 | HandleScope scope(isolate); |
Steve Block | 44f0eee | 2011-05-26 01:26:41 +0100 | [diff] [blame] | 46 | int length = cache_->length(); |
Ben Murdoch | b8a8cc1 | 2014-11-26 15:28:44 +0000 | [diff] [blame] | 47 | Handle<FixedArray> new_array = factory->NewFixedArray(length + 2, TENURED); |
Steve Block | 44f0eee | 2011-05-26 01:26:41 +0100 | [diff] [blame] | 48 | cache_->CopyTo(0, *new_array, 0, cache_->length()); |
| 49 | cache_ = *new_array; |
Ben Murdoch | b8a8cc1 | 2014-11-26 15:28:44 +0000 | [diff] [blame] | 50 | Handle<String> str = |
| 51 | factory->NewStringFromAscii(name, TENURED).ToHandleChecked(); |
| 52 | DCHECK(!str.is_null()); |
Steve Block | 44f0eee | 2011-05-26 01:26:41 +0100 | [diff] [blame] | 53 | cache_->set(length, *str); |
| 54 | cache_->set(length + 1, *shared); |
Ben Murdoch | 4a90d5f | 2016-03-22 12:00:34 +0000 | [diff] [blame] | 55 | Script::cast(shared->script())->set_type(type_); |
Steve Block | 44f0eee | 2011-05-26 01:26:41 +0100 | [diff] [blame] | 56 | } |
Andrei Popescu | 3100271 | 2010-02-23 13:46:05 +0000 | [diff] [blame] | 57 | |
| 58 | private: |
Steve Block | 44f0eee | 2011-05-26 01:26:41 +0100 | [diff] [blame] | 59 | Script::Type type_; |
| 60 | FixedArray* cache_; |
| 61 | DISALLOW_COPY_AND_ASSIGN(SourceCodeCache); |
Andrei Popescu | 3100271 | 2010-02-23 13:46:05 +0000 | [diff] [blame] | 62 | }; |
| 63 | |
Ben Murdoch | 61f157c | 2016-09-16 13:49:30 +0100 | [diff] [blame] | 64 | enum GlobalContextType { FULL_CONTEXT, DEBUG_CONTEXT }; |
Andrei Popescu | 3100271 | 2010-02-23 13:46:05 +0000 | [diff] [blame] | 65 | |
Steve Block | a7e24c1 | 2009-10-30 11:49:00 +0000 | [diff] [blame] | 66 | // The Boostrapper is the public interface for creating a JavaScript global |
| 67 | // context. |
Ben Murdoch | 4a90d5f | 2016-03-22 12:00:34 +0000 | [diff] [blame] | 68 | class Bootstrapper final { |
Steve Block | a7e24c1 | 2009-10-30 11:49:00 +0000 | [diff] [blame] | 69 | public: |
Ben Murdoch | b8a8cc1 | 2014-11-26 15:28:44 +0000 | [diff] [blame] | 70 | static void InitializeOncePerProcess(); |
| 71 | static void TearDownExtensions(); |
| 72 | |
Ben Murdoch | 3ef787d | 2012-04-12 10:51:47 +0100 | [diff] [blame] | 73 | // Requires: Heap::SetUp has been called. |
Steve Block | 44f0eee | 2011-05-26 01:26:41 +0100 | [diff] [blame] | 74 | void Initialize(bool create_heap_objects); |
| 75 | void TearDown(); |
Steve Block | a7e24c1 | 2009-10-30 11:49:00 +0000 | [diff] [blame] | 76 | |
| 77 | // Creates a JavaScript Global Context with initial object graph. |
| 78 | // The returned value is a global handle casted to V8Environment*. |
Steve Block | 44f0eee | 2011-05-26 01:26:41 +0100 | [diff] [blame] | 79 | Handle<Context> CreateEnvironment( |
Ben Murdoch | b8a8cc1 | 2014-11-26 15:28:44 +0000 | [diff] [blame] | 80 | MaybeHandle<JSGlobalProxy> maybe_global_proxy, |
Ben Murdoch | 4a90d5f | 2016-03-22 12:00:34 +0000 | [diff] [blame] | 81 | v8::Local<v8::ObjectTemplate> global_object_template, |
Ben Murdoch | 61f157c | 2016-09-16 13:49:30 +0100 | [diff] [blame] | 82 | v8::ExtensionConfiguration* extensions, size_t context_snapshot_index, |
Ben Murdoch | 097c5b2 | 2016-05-18 11:27:45 +0100 | [diff] [blame] | 83 | GlobalContextType context_type = FULL_CONTEXT); |
Steve Block | a7e24c1 | 2009-10-30 11:49:00 +0000 | [diff] [blame] | 84 | |
| 85 | // Detach the environment from its outer global object. |
Steve Block | 44f0eee | 2011-05-26 01:26:41 +0100 | [diff] [blame] | 86 | void DetachGlobal(Handle<Context> env); |
Steve Block | a7e24c1 | 2009-10-30 11:49:00 +0000 | [diff] [blame] | 87 | |
| 88 | // Traverses the pointers for memory management. |
Steve Block | 44f0eee | 2011-05-26 01:26:41 +0100 | [diff] [blame] | 89 | void Iterate(ObjectVisitor* v); |
Steve Block | a7e24c1 | 2009-10-30 11:49:00 +0000 | [diff] [blame] | 90 | |
Steve Block | 6ded16b | 2010-05-10 14:33:55 +0100 | [diff] [blame] | 91 | // Accessor for the native scripts source code. |
Ben Murdoch | 4a90d5f | 2016-03-22 12:00:34 +0000 | [diff] [blame] | 92 | template <class Source> |
| 93 | Handle<String> SourceLookup(int index); |
Steve Block | a7e24c1 | 2009-10-30 11:49:00 +0000 | [diff] [blame] | 94 | |
Steve Block | a7e24c1 | 2009-10-30 11:49:00 +0000 | [diff] [blame] | 95 | // Tells whether bootstrapping is active. |
Steve Block | 44f0eee | 2011-05-26 01:26:41 +0100 | [diff] [blame] | 96 | bool IsActive() const { return nesting_ != 0; } |
Steve Block | a7e24c1 | 2009-10-30 11:49:00 +0000 | [diff] [blame] | 97 | |
Steve Block | a7e24c1 | 2009-10-30 11:49:00 +0000 | [diff] [blame] | 98 | // Support for thread preemption. |
Ben Murdoch | 257744e | 2011-11-30 15:57:28 +0000 | [diff] [blame] | 99 | static int ArchiveSpacePerThread(); |
Steve Block | 44f0eee | 2011-05-26 01:26:41 +0100 | [diff] [blame] | 100 | char* ArchiveState(char* to); |
| 101 | char* RestoreState(char* from); |
| 102 | void FreeThreadResources(); |
Leon Clarke | e46be81 | 2010-01-19 14:06:41 +0000 | [diff] [blame] | 103 | |
Andrei Popescu | 3100271 | 2010-02-23 13:46:05 +0000 | [diff] [blame] | 104 | // Used for new context creation. |
Ben Murdoch | b8a8cc1 | 2014-11-26 15:28:44 +0000 | [diff] [blame] | 105 | bool InstallExtensions(Handle<Context> native_context, |
Steve Block | 44f0eee | 2011-05-26 01:26:41 +0100 | [diff] [blame] | 106 | v8::ExtensionConfiguration* extensions); |
| 107 | |
| 108 | SourceCodeCache* extensions_cache() { return &extensions_cache_; } |
| 109 | |
Ben Murdoch | 4a90d5f | 2016-03-22 12:00:34 +0000 | [diff] [blame] | 110 | static bool CompileNative(Isolate* isolate, Vector<const char> name, |
| 111 | Handle<String> source, int argc, |
Ben Murdoch | 097c5b2 | 2016-05-18 11:27:45 +0100 | [diff] [blame] | 112 | Handle<Object> argv[], NativesFlag natives_flag); |
Ben Murdoch | 4a90d5f | 2016-03-22 12:00:34 +0000 | [diff] [blame] | 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 | |
Steve Block | 44f0eee | 2011-05-26 01:26:41 +0100 | [diff] [blame] | 122 | private: |
Ben Murdoch | b8a8cc1 | 2014-11-26 15:28:44 +0000 | [diff] [blame] | 123 | Isolate* isolate_; |
Steve Block | 44f0eee | 2011-05-26 01:26:41 +0100 | [diff] [blame] | 124 | typedef int NestingCounterType; |
| 125 | NestingCounterType nesting_; |
| 126 | SourceCodeCache extensions_cache_; |
Steve Block | 44f0eee | 2011-05-26 01:26:41 +0100 | [diff] [blame] | 127 | |
| 128 | friend class BootstrapperActive; |
| 129 | friend class Isolate; |
| 130 | friend class NativesExternalStringResource; |
| 131 | |
Ben Murdoch | b8a8cc1 | 2014-11-26 15:28:44 +0000 | [diff] [blame] | 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_; |
Ben Murdoch | c561043 | 2016-08-08 18:44:38 +0100 | [diff] [blame] | 139 | static v8::Extension* ignition_statistics_extension_; |
Steve Block | 44f0eee | 2011-05-26 01:26:41 +0100 | [diff] [blame] | 140 | |
| 141 | DISALLOW_COPY_AND_ASSIGN(Bootstrapper); |
| 142 | }; |
| 143 | |
| 144 | |
Ben Murdoch | 4a90d5f | 2016-03-22 12:00:34 +0000 | [diff] [blame] | 145 | class BootstrapperActive final BASE_EMBEDDED { |
Steve Block | 44f0eee | 2011-05-26 01:26:41 +0100 | [diff] [blame] | 146 | public: |
Ben Murdoch | b8a8cc1 | 2014-11-26 15:28:44 +0000 | [diff] [blame] | 147 | explicit BootstrapperActive(Bootstrapper* bootstrapper) |
| 148 | : bootstrapper_(bootstrapper) { |
| 149 | ++bootstrapper_->nesting_; |
Steve Block | 44f0eee | 2011-05-26 01:26:41 +0100 | [diff] [blame] | 150 | } |
| 151 | |
| 152 | ~BootstrapperActive() { |
Ben Murdoch | b8a8cc1 | 2014-11-26 15:28:44 +0000 | [diff] [blame] | 153 | --bootstrapper_->nesting_; |
Steve Block | 44f0eee | 2011-05-26 01:26:41 +0100 | [diff] [blame] | 154 | } |
| 155 | |
| 156 | private: |
Ben Murdoch | b8a8cc1 | 2014-11-26 15:28:44 +0000 | [diff] [blame] | 157 | Bootstrapper* bootstrapper_; |
| 158 | |
Steve Block | 44f0eee | 2011-05-26 01:26:41 +0100 | [diff] [blame] | 159 | DISALLOW_COPY_AND_ASSIGN(BootstrapperActive); |
Steve Block | a7e24c1 | 2009-10-30 11:49:00 +0000 | [diff] [blame] | 160 | }; |
| 161 | |
Steve Block | d0582a6 | 2009-12-15 09:54:21 +0000 | [diff] [blame] | 162 | |
Ben Murdoch | 4a90d5f | 2016-03-22 12:00:34 +0000 | [diff] [blame] | 163 | class NativesExternalStringResource final |
Ben Murdoch | b8a8cc1 | 2014-11-26 15:28:44 +0000 | [diff] [blame] | 164 | : public v8::String::ExternalOneByteStringResource { |
Steve Block | d0582a6 | 2009-12-15 09:54:21 +0000 | [diff] [blame] | 165 | public: |
Ben Murdoch | 4a90d5f | 2016-03-22 12:00:34 +0000 | [diff] [blame] | 166 | NativesExternalStringResource(const char* source, size_t length) |
| 167 | : data_(source), length_(length) {} |
| 168 | const char* data() const override { return data_; } |
| 169 | size_t length() const override { return length_; } |
Steve Block | d0582a6 | 2009-12-15 09:54:21 +0000 | [diff] [blame] | 170 | |
Steve Block | d0582a6 | 2009-12-15 09:54:21 +0000 | [diff] [blame] | 171 | private: |
| 172 | const char* data_; |
| 173 | size_t length_; |
| 174 | }; |
| 175 | |
Ben Murdoch | 4a90d5f | 2016-03-22 12:00:34 +0000 | [diff] [blame] | 176 | } // namespace internal |
| 177 | } // namespace v8 |
Steve Block | a7e24c1 | 2009-10-30 11:49:00 +0000 | [diff] [blame] | 178 | |
| 179 | #endif // V8_BOOTSTRAPPER_H_ |