| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| (...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 94 isolate_); | 94 isolate_); |
| 95 return Handle<String>::cast(cached_source); | 95 return Handle<String>::cast(cached_source); |
| 96 } | 96 } |
| 97 | 97 |
| 98 | 98 |
| 99 void Bootstrapper::Initialize(bool create_heap_objects) { | 99 void Bootstrapper::Initialize(bool create_heap_objects) { |
| 100 extensions_cache_.Initialize(isolate_, create_heap_objects); | 100 extensions_cache_.Initialize(isolate_, create_heap_objects); |
| 101 } | 101 } |
| 102 | 102 |
| 103 | 103 |
| 104 void Bootstrapper::InitializeOncePerProcess() { | 104 static const char* GCFunctionName() { |
| 105 #ifdef ADDRESS_SANITIZER | 105 bool flag_given = FLAG_expose_gc_as != NULL && strlen(FLAG_expose_gc_as) != 0; |
| 106 FreeBufferExtension::Register(); | 106 return flag_given ? FLAG_expose_gc_as : "gc"; |
| 107 #endif | |
| 108 GCExtension::Register(); | |
| 109 ExternalizeStringExtension::Register(); | |
| 110 StatisticsExtension::Register(); | |
| 111 TriggerFailureExtension::Register(); | |
| 112 } | 107 } |
| 113 | 108 |
| 114 | 109 |
| 110 v8::Extension* Bootstrapper::free_buffer_extension_ = NULL; |
| 111 v8::Extension* Bootstrapper::gc_extension_ = NULL; |
| 112 v8::Extension* Bootstrapper::externalize_string_extension_ = NULL; |
| 113 v8::Extension* Bootstrapper::statistics_extension_ = NULL; |
| 114 v8::Extension* Bootstrapper::trigger_failure_extension_ = NULL; |
| 115 |
| 116 |
| 117 void Bootstrapper::InitializeOncePerProcess() { |
| 118 free_buffer_extension_ = new FreeBufferExtension; |
| 119 v8::RegisterExtension(free_buffer_extension_); |
| 120 gc_extension_ = new GCExtension(GCFunctionName()); |
| 121 v8::RegisterExtension(gc_extension_); |
| 122 externalize_string_extension_ = new ExternalizeStringExtension; |
| 123 v8::RegisterExtension(externalize_string_extension_); |
| 124 statistics_extension_ = new StatisticsExtension; |
| 125 v8::RegisterExtension(statistics_extension_); |
| 126 trigger_failure_extension_ = new TriggerFailureExtension; |
| 127 v8::RegisterExtension(trigger_failure_extension_); |
| 128 } |
| 129 |
| 130 |
| 131 void Bootstrapper::TearDownExtensions() { |
| 132 delete free_buffer_extension_; |
| 133 delete gc_extension_; |
| 134 delete externalize_string_extension_; |
| 135 delete statistics_extension_; |
| 136 delete trigger_failure_extension_; |
| 137 } |
| 138 |
| 139 |
| 115 char* Bootstrapper::AllocateAutoDeletedArray(int bytes) { | 140 char* Bootstrapper::AllocateAutoDeletedArray(int bytes) { |
| 116 char* memory = new char[bytes]; | 141 char* memory = new char[bytes]; |
| 117 if (memory != NULL) { | 142 if (memory != NULL) { |
| 118 if (delete_these_arrays_on_tear_down_ == NULL) { | 143 if (delete_these_arrays_on_tear_down_ == NULL) { |
| 119 delete_these_arrays_on_tear_down_ = new List<char*>(2); | 144 delete_these_arrays_on_tear_down_ = new List<char*>(2); |
| 120 } | 145 } |
| 121 delete_these_arrays_on_tear_down_->Add(memory); | 146 delete_these_arrays_on_tear_down_->Add(memory); |
| 122 } | 147 } |
| 123 return memory; | 148 return memory; |
| 124 } | 149 } |
| (...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 231 ExtensionTraversalState state); | 256 ExtensionTraversalState state); |
| 232 private: | 257 private: |
| 233 HashMap map_; | 258 HashMap map_; |
| 234 DISALLOW_COPY_AND_ASSIGN(ExtensionStates); | 259 DISALLOW_COPY_AND_ASSIGN(ExtensionStates); |
| 235 }; | 260 }; |
| 236 | 261 |
| 237 // Used both for deserialized and from-scratch contexts to add the extensions | 262 // Used both for deserialized and from-scratch contexts to add the extensions |
| 238 // provided. | 263 // provided. |
| 239 static bool InstallExtensions(Handle<Context> native_context, | 264 static bool InstallExtensions(Handle<Context> native_context, |
| 240 v8::ExtensionConfiguration* extensions); | 265 v8::ExtensionConfiguration* extensions); |
| 266 static bool InstallAutoExtensions(Isolate* isolate, |
| 267 ExtensionStates* extension_states); |
| 268 static bool InstallRequestedExtensions(Isolate* isolate, |
| 269 v8::ExtensionConfiguration* extensions, |
| 270 ExtensionStates* extension_states); |
| 241 static bool InstallExtension(Isolate* isolate, | 271 static bool InstallExtension(Isolate* isolate, |
| 242 const char* name, | 272 const char* name, |
| 243 ExtensionStates* extension_states); | 273 ExtensionStates* extension_states); |
| 244 static bool InstallExtension(Isolate* isolate, | 274 static bool InstallExtension(Isolate* isolate, |
| 245 v8::RegisteredExtension* current, | 275 v8::RegisteredExtension* current, |
| 246 ExtensionStates* extension_states); | 276 ExtensionStates* extension_states); |
| 247 static void InstallSpecialObjects(Handle<Context> native_context); | 277 static bool InstallSpecialObjects(Handle<Context> native_context); |
| 248 bool InstallJSBuiltins(Handle<JSBuiltinsObject> builtins); | 278 bool InstallJSBuiltins(Handle<JSBuiltinsObject> builtins); |
| 249 bool ConfigureApiObject(Handle<JSObject> object, | 279 bool ConfigureApiObject(Handle<JSObject> object, |
| 250 Handle<ObjectTemplateInfo> object_template); | 280 Handle<ObjectTemplateInfo> object_template); |
| 251 bool ConfigureGlobalObjects(v8::Handle<v8::ObjectTemplate> global_template); | 281 bool ConfigureGlobalObjects(v8::Handle<v8::ObjectTemplate> global_template); |
| 252 | 282 |
| 253 // Migrates all properties from the 'from' object to the 'to' | 283 // Migrates all properties from the 'from' object to the 'to' |
| 254 // object and overrides the prototype in 'to' with the one from | 284 // object and overrides the prototype in 'to' with the one from |
| 255 // 'from'. | 285 // 'from'. |
| 256 void TransferObject(Handle<JSObject> from, Handle<JSObject> to); | 286 void TransferObject(Handle<JSObject> from, Handle<JSObject> to); |
| 257 void TransferNamedProperties(Handle<JSObject> from, Handle<JSObject> to); | 287 void TransferNamedProperties(Handle<JSObject> from, Handle<JSObject> to); |
| (...skipping 1887 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2145 factory()->NewFixedArray(NormalizedMapCache::kEntries, TENURED)); | 2175 factory()->NewFixedArray(NormalizedMapCache::kEntries, TENURED)); |
| 2146 native_context()->set_normalized_map_cache(NormalizedMapCache::cast(*array)); | 2176 native_context()->set_normalized_map_cache(NormalizedMapCache::cast(*array)); |
| 2147 } | 2177 } |
| 2148 | 2178 |
| 2149 | 2179 |
| 2150 bool Bootstrapper::InstallExtensions(Handle<Context> native_context, | 2180 bool Bootstrapper::InstallExtensions(Handle<Context> native_context, |
| 2151 v8::ExtensionConfiguration* extensions) { | 2181 v8::ExtensionConfiguration* extensions) { |
| 2152 BootstrapperActive active(this); | 2182 BootstrapperActive active(this); |
| 2153 SaveContext saved_context(isolate_); | 2183 SaveContext saved_context(isolate_); |
| 2154 isolate_->set_context(*native_context); | 2184 isolate_->set_context(*native_context); |
| 2155 if (!Genesis::InstallExtensions(native_context, extensions)) return false; | 2185 return Genesis::InstallExtensions(native_context, extensions) && |
| 2156 Genesis::InstallSpecialObjects(native_context); | 2186 Genesis::InstallSpecialObjects(native_context); |
| 2157 return true; | |
| 2158 } | 2187 } |
| 2159 | 2188 |
| 2160 | 2189 |
| 2161 void Genesis::InstallSpecialObjects(Handle<Context> native_context) { | 2190 bool Genesis::InstallSpecialObjects(Handle<Context> native_context) { |
| 2162 Isolate* isolate = native_context->GetIsolate(); | 2191 Isolate* isolate = native_context->GetIsolate(); |
| 2163 Factory* factory = isolate->factory(); | 2192 Factory* factory = isolate->factory(); |
| 2164 HandleScope scope(isolate); | 2193 HandleScope scope(isolate); |
| 2165 Handle<JSGlobalObject> global(JSGlobalObject::cast( | 2194 Handle<JSGlobalObject> global(JSGlobalObject::cast( |
| 2166 native_context->global_object())); | 2195 native_context->global_object())); |
| 2167 // Expose the natives in global if a name for it is specified. | 2196 // Expose the natives in global if a name for it is specified. |
| 2168 if (FLAG_expose_natives_as != NULL && strlen(FLAG_expose_natives_as) != 0) { | 2197 if (FLAG_expose_natives_as != NULL && strlen(FLAG_expose_natives_as) != 0) { |
| 2169 Handle<String> natives = | 2198 Handle<String> natives = |
| 2170 factory->InternalizeUtf8String(FLAG_expose_natives_as); | 2199 factory->InternalizeUtf8String(FLAG_expose_natives_as); |
| 2171 CHECK_NOT_EMPTY_HANDLE(isolate, | 2200 JSObject::SetLocalPropertyIgnoreAttributes( |
| 2172 JSObject::SetLocalPropertyIgnoreAttributes( | 2201 global, natives, Handle<JSObject>(global->builtins()), DONT_ENUM); |
| 2173 global, natives, | 2202 if (isolate->has_pending_exception()) return false; |
| 2174 Handle<JSObject>(global->builtins()), | |
| 2175 DONT_ENUM)); | |
| 2176 } | 2203 } |
| 2177 | 2204 |
| 2178 Handle<Object> Error = GetProperty(global, "Error"); | 2205 Handle<Object> Error = GetProperty(global, "Error"); |
| 2179 if (Error->IsJSObject()) { | 2206 if (Error->IsJSObject()) { |
| 2180 Handle<String> name = factory->InternalizeOneByteString( | 2207 Handle<String> name = factory->InternalizeOneByteString( |
| 2181 STATIC_ASCII_VECTOR("stackTraceLimit")); | 2208 STATIC_ASCII_VECTOR("stackTraceLimit")); |
| 2182 Handle<Smi> stack_trace_limit( | 2209 Handle<Smi> stack_trace_limit( |
| 2183 Smi::FromInt(FLAG_stack_trace_limit), isolate); | 2210 Smi::FromInt(FLAG_stack_trace_limit), isolate); |
| 2184 CHECK_NOT_EMPTY_HANDLE(isolate, | 2211 JSObject::SetLocalPropertyIgnoreAttributes( |
| 2185 JSObject::SetLocalPropertyIgnoreAttributes( | 2212 Handle<JSObject>::cast(Error), name, stack_trace_limit, NONE); |
| 2186 Handle<JSObject>::cast(Error), name, | 2213 if (isolate->has_pending_exception()) return false; |
| 2187 stack_trace_limit, NONE)); | |
| 2188 } | 2214 } |
| 2189 | 2215 |
| 2190 #ifdef ENABLE_DEBUGGER_SUPPORT | 2216 #ifdef ENABLE_DEBUGGER_SUPPORT |
| 2191 // Expose the debug global object in global if a name for it is specified. | 2217 // Expose the debug global object in global if a name for it is specified. |
| 2192 if (FLAG_expose_debug_as != NULL && strlen(FLAG_expose_debug_as) != 0) { | 2218 if (FLAG_expose_debug_as != NULL && strlen(FLAG_expose_debug_as) != 0) { |
| 2193 Debug* debug = isolate->debug(); | 2219 Debug* debug = isolate->debug(); |
| 2194 // If loading fails we just bail out without installing the | 2220 // If loading fails we just bail out without installing the |
| 2195 // debugger but without tanking the whole context. | 2221 // debugger but without tanking the whole context. |
| 2196 if (!debug->Load()) return; | 2222 if (!debug->Load()) return true; |
| 2197 // Set the security token for the debugger context to the same as | 2223 // Set the security token for the debugger context to the same as |
| 2198 // the shell native context to allow calling between these (otherwise | 2224 // the shell native context to allow calling between these (otherwise |
| 2199 // exposing debug global object doesn't make much sense). | 2225 // exposing debug global object doesn't make much sense). |
| 2200 debug->debug_context()->set_security_token( | 2226 debug->debug_context()->set_security_token( |
| 2201 native_context->security_token()); | 2227 native_context->security_token()); |
| 2202 | 2228 |
| 2203 Handle<String> debug_string = | 2229 Handle<String> debug_string = |
| 2204 factory->InternalizeUtf8String(FLAG_expose_debug_as); | 2230 factory->InternalizeUtf8String(FLAG_expose_debug_as); |
| 2205 Handle<Object> global_proxy( | 2231 Handle<Object> global_proxy( |
| 2206 debug->debug_context()->global_proxy(), isolate); | 2232 debug->debug_context()->global_proxy(), isolate); |
| 2207 CHECK_NOT_EMPTY_HANDLE(isolate, | 2233 JSObject::SetLocalPropertyIgnoreAttributes( |
| 2208 JSObject::SetLocalPropertyIgnoreAttributes( | 2234 global, debug_string, global_proxy, DONT_ENUM); |
| 2209 global, debug_string, global_proxy, DONT_ENUM)); | 2235 if (isolate->has_pending_exception()) return false; |
| 2210 } | 2236 } |
| 2211 #endif | 2237 #endif |
| 2238 return true; |
| 2212 } | 2239 } |
| 2213 | 2240 |
| 2214 | 2241 |
| 2215 static uint32_t Hash(RegisteredExtension* extension) { | 2242 static uint32_t Hash(RegisteredExtension* extension) { |
| 2216 return v8::internal::ComputePointerHash(extension); | 2243 return v8::internal::ComputePointerHash(extension); |
| 2217 } | 2244 } |
| 2218 | 2245 |
| 2219 | 2246 |
| 2220 static bool MatchRegisteredExtensions(void* key1, void* key2) { | 2247 static bool MatchRegisteredExtensions(void* key1, void* key2) { |
| 2221 return key1 == key2; | 2248 return key1 == key2; |
| (...skipping 11 matching lines...) Expand all Loading... |
| 2233 return static_cast<ExtensionTraversalState>( | 2260 return static_cast<ExtensionTraversalState>( |
| 2234 reinterpret_cast<intptr_t>(entry->value)); | 2261 reinterpret_cast<intptr_t>(entry->value)); |
| 2235 } | 2262 } |
| 2236 | 2263 |
| 2237 void Genesis::ExtensionStates::set_state(RegisteredExtension* extension, | 2264 void Genesis::ExtensionStates::set_state(RegisteredExtension* extension, |
| 2238 ExtensionTraversalState state) { | 2265 ExtensionTraversalState state) { |
| 2239 map_.Lookup(extension, Hash(extension), true)->value = | 2266 map_.Lookup(extension, Hash(extension), true)->value = |
| 2240 reinterpret_cast<void*>(static_cast<intptr_t>(state)); | 2267 reinterpret_cast<void*>(static_cast<intptr_t>(state)); |
| 2241 } | 2268 } |
| 2242 | 2269 |
| 2270 |
| 2243 bool Genesis::InstallExtensions(Handle<Context> native_context, | 2271 bool Genesis::InstallExtensions(Handle<Context> native_context, |
| 2244 v8::ExtensionConfiguration* extensions) { | 2272 v8::ExtensionConfiguration* extensions) { |
| 2245 Isolate* isolate = native_context->GetIsolate(); | 2273 Isolate* isolate = native_context->GetIsolate(); |
| 2246 ExtensionStates extension_states; // All extensions have state UNVISITED. | 2274 ExtensionStates extension_states; // All extensions have state UNVISITED. |
| 2247 // Install auto extensions. | 2275 return InstallAutoExtensions(isolate, &extension_states) && |
| 2248 v8::RegisteredExtension* current = v8::RegisteredExtension::first_extension(); | 2276 (!FLAG_expose_free_buffer || |
| 2249 while (current != NULL) { | 2277 InstallExtension(isolate, "v8/free-buffer", &extension_states)) && |
| 2250 if (current->extension()->auto_enable()) | 2278 (!FLAG_expose_gc || |
| 2251 InstallExtension(isolate, current, &extension_states); | 2279 InstallExtension(isolate, "v8/gc", &extension_states)) && |
| 2252 current = current->next(); | 2280 (!FLAG_expose_externalize_string || |
| 2281 InstallExtension(isolate, "v8/externalize", &extension_states)) && |
| 2282 (!FLAG_track_gc_object_stats || |
| 2283 InstallExtension(isolate, "v8/statistics", &extension_states)) && |
| 2284 (!FLAG_expose_trigger_failure || |
| 2285 InstallExtension(isolate, "v8/trigger-failure", &extension_states)) && |
| 2286 InstallRequestedExtensions(isolate, extensions, &extension_states); |
| 2287 } |
| 2288 |
| 2289 |
| 2290 bool Genesis::InstallAutoExtensions(Isolate* isolate, |
| 2291 ExtensionStates* extension_states) { |
| 2292 for (v8::RegisteredExtension* it = v8::RegisteredExtension::first_extension(); |
| 2293 it != NULL; |
| 2294 it = it->next()) { |
| 2295 if (it->extension()->auto_enable() && |
| 2296 !InstallExtension(isolate, it, extension_states)) { |
| 2297 return false; |
| 2298 } |
| 2253 } | 2299 } |
| 2254 | |
| 2255 #ifdef ADDRESS_SANITIZER | |
| 2256 if (FLAG_expose_free_buffer) { | |
| 2257 InstallExtension(isolate, "v8/free-buffer", &extension_states); | |
| 2258 } | |
| 2259 #endif | |
| 2260 if (FLAG_expose_gc) InstallExtension(isolate, "v8/gc", &extension_states); | |
| 2261 if (FLAG_expose_externalize_string) { | |
| 2262 InstallExtension(isolate, "v8/externalize", &extension_states); | |
| 2263 } | |
| 2264 if (FLAG_track_gc_object_stats) { | |
| 2265 InstallExtension(isolate, "v8/statistics", &extension_states); | |
| 2266 } | |
| 2267 if (FLAG_expose_trigger_failure) { | |
| 2268 InstallExtension(isolate, "v8/trigger-failure", &extension_states); | |
| 2269 } | |
| 2270 | |
| 2271 for (const char** it = extensions->begin(); it != extensions->end(); ++it) { | |
| 2272 if (!InstallExtension(isolate, *it, &extension_states)) return false; | |
| 2273 } | |
| 2274 | |
| 2275 return true; | 2300 return true; |
| 2276 } | 2301 } |
| 2277 | 2302 |
| 2303 |
| 2304 bool Genesis::InstallRequestedExtensions(Isolate* isolate, |
| 2305 v8::ExtensionConfiguration* extensions, |
| 2306 ExtensionStates* extension_states) { |
| 2307 for (const char** it = extensions->begin(); it != extensions->end(); ++it) { |
| 2308 if (!InstallExtension(isolate, *it, extension_states)) return false; |
| 2309 } |
| 2310 return true; |
| 2311 } |
| 2312 |
| 2278 | 2313 |
| 2279 // Installs a named extension. This methods is unoptimized and does | 2314 // Installs a named extension. This methods is unoptimized and does |
| 2280 // not scale well if we want to support a large number of extensions. | 2315 // not scale well if we want to support a large number of extensions. |
| 2281 bool Genesis::InstallExtension(Isolate* isolate, | 2316 bool Genesis::InstallExtension(Isolate* isolate, |
| 2282 const char* name, | 2317 const char* name, |
| 2283 ExtensionStates* extension_states) { | 2318 ExtensionStates* extension_states) { |
| 2284 v8::RegisteredExtension* current = v8::RegisteredExtension::first_extension(); | 2319 for (v8::RegisteredExtension* it = v8::RegisteredExtension::first_extension(); |
| 2285 // Loop until we find the relevant extension | 2320 it != NULL; |
| 2286 while (current != NULL) { | 2321 it = it->next()) { |
| 2287 if (strcmp(name, current->extension()->name()) == 0) break; | 2322 if (strcmp(name, it->extension()->name()) == 0) { |
| 2288 current = current->next(); | 2323 return InstallExtension(isolate, it, extension_states); |
| 2324 } |
| 2289 } | 2325 } |
| 2290 // Didn't find the extension; fail. | 2326 return Utils::ApiCheck(false, |
| 2291 if (!Utils::ApiCheck(current != NULL, | 2327 "v8::Context::New()", |
| 2292 "v8::Context::New()", | 2328 "Cannot find required extension"); |
| 2293 "Cannot find required extension")) { | |
| 2294 return false; | |
| 2295 } | |
| 2296 return InstallExtension(isolate, current, extension_states); | |
| 2297 } | 2329 } |
| 2298 | 2330 |
| 2299 | 2331 |
| 2300 bool Genesis::InstallExtension(Isolate* isolate, | 2332 bool Genesis::InstallExtension(Isolate* isolate, |
| 2301 v8::RegisteredExtension* current, | 2333 v8::RegisteredExtension* current, |
| 2302 ExtensionStates* extension_states) { | 2334 ExtensionStates* extension_states) { |
| 2303 HandleScope scope(isolate); | 2335 HandleScope scope(isolate); |
| 2304 | 2336 |
| 2305 if (extension_states->get_state(current) == INSTALLED) return true; | 2337 if (extension_states->get_state(current) == INSTALLED) return true; |
| 2306 // The current node has already been visited so there must be a | 2338 // The current node has already been visited so there must be a |
| (...skipping 394 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2701 return from + sizeof(NestingCounterType); | 2733 return from + sizeof(NestingCounterType); |
| 2702 } | 2734 } |
| 2703 | 2735 |
| 2704 | 2736 |
| 2705 // Called when the top-level V8 mutex is destroyed. | 2737 // Called when the top-level V8 mutex is destroyed. |
| 2706 void Bootstrapper::FreeThreadResources() { | 2738 void Bootstrapper::FreeThreadResources() { |
| 2707 ASSERT(!IsActive()); | 2739 ASSERT(!IsActive()); |
| 2708 } | 2740 } |
| 2709 | 2741 |
| 2710 } } // namespace v8::internal | 2742 } } // namespace v8::internal |
| OLD | NEW |