| OLD | NEW |
| 1 // Copyright 2014 the V8 project authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "src/bootstrapper.h" | 5 #include "src/bootstrapper.h" |
| 6 | 6 |
| 7 #include "src/accessors.h" | 7 #include "src/accessors.h" |
| 8 #include "src/code-stubs.h" | 8 #include "src/code-stubs.h" |
| 9 #include "src/extensions/externalize-string-extension.h" | 9 #include "src/extensions/externalize-string-extension.h" |
| 10 #include "src/extensions/free-buffer-extension.h" | 10 #include "src/extensions/free-buffer-extension.h" |
| (...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 119 } | 119 } |
| 120 delete_these_arrays_on_tear_down_->Add(memory); | 120 delete_these_arrays_on_tear_down_->Add(memory); |
| 121 } | 121 } |
| 122 return memory; | 122 return memory; |
| 123 } | 123 } |
| 124 | 124 |
| 125 | 125 |
| 126 void Bootstrapper::TearDown() { | 126 void Bootstrapper::TearDown() { |
| 127 if (delete_these_non_arrays_on_tear_down_ != NULL) { | 127 if (delete_these_non_arrays_on_tear_down_ != NULL) { |
| 128 int len = delete_these_non_arrays_on_tear_down_->length(); | 128 int len = delete_these_non_arrays_on_tear_down_->length(); |
| 129 DCHECK(len < 27); // Don't use this mechanism for unbounded allocations. | 129 DCHECK(len < 28); // Don't use this mechanism for unbounded allocations. |
| 130 for (int i = 0; i < len; i++) { | 130 for (int i = 0; i < len; i++) { |
| 131 delete delete_these_non_arrays_on_tear_down_->at(i); | 131 delete delete_these_non_arrays_on_tear_down_->at(i); |
| 132 delete_these_non_arrays_on_tear_down_->at(i) = NULL; | 132 delete_these_non_arrays_on_tear_down_->at(i) = NULL; |
| 133 } | 133 } |
| 134 delete delete_these_non_arrays_on_tear_down_; | 134 delete delete_these_non_arrays_on_tear_down_; |
| 135 delete_these_non_arrays_on_tear_down_ = NULL; | 135 delete_these_non_arrays_on_tear_down_ = NULL; |
| 136 } | 136 } |
| 137 | 137 |
| 138 if (delete_these_arrays_on_tear_down_ != NULL) { | 138 if (delete_these_arrays_on_tear_down_ != NULL) { |
| 139 int len = delete_these_arrays_on_tear_down_->length(); | 139 int len = delete_these_arrays_on_tear_down_->length(); |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 196 // deserialized, leaving the GC to pick it up. | 196 // deserialized, leaving the GC to pick it up. |
| 197 void HookUpGlobalProxy(Handle<GlobalObject> global_object, | 197 void HookUpGlobalProxy(Handle<GlobalObject> global_object, |
| 198 Handle<JSGlobalProxy> global_proxy); | 198 Handle<JSGlobalProxy> global_proxy); |
| 199 // Similarly, we want to use the global that has been created by the templates | 199 // Similarly, we want to use the global that has been created by the templates |
| 200 // passed through the API. The global from the snapshot is detached from the | 200 // passed through the API. The global from the snapshot is detached from the |
| 201 // other objects in the snapshot. | 201 // other objects in the snapshot. |
| 202 void HookUpGlobalObject(Handle<GlobalObject> global_object); | 202 void HookUpGlobalObject(Handle<GlobalObject> global_object); |
| 203 // New context initialization. Used for creating a context from scratch. | 203 // New context initialization. Used for creating a context from scratch. |
| 204 void InitializeGlobal(Handle<GlobalObject> global_object, | 204 void InitializeGlobal(Handle<GlobalObject> global_object, |
| 205 Handle<JSFunction> empty_function); | 205 Handle<JSFunction> empty_function); |
| 206 void InitializeExperimentalGlobal(); | |
| 207 // Installs the contents of the native .js files on the global objects. | 206 // Installs the contents of the native .js files on the global objects. |
| 208 // Used for creating a context from scratch. | 207 // Used for creating a context from scratch. |
| 209 void InstallNativeFunctions(); | 208 void InstallNativeFunctions(); |
| 210 void InstallExperimentalNativeFunctions(); | 209 void InstallExperimentalNativeFunctions(); |
| 211 Handle<JSFunction> InstallInternalArray(Handle<JSBuiltinsObject> builtins, | 210 Handle<JSFunction> InstallInternalArray(Handle<JSBuiltinsObject> builtins, |
| 212 const char* name, | 211 const char* name, |
| 213 ElementsKind elements_kind); | 212 ElementsKind elements_kind); |
| 214 bool InstallNatives(); | 213 bool InstallNatives(); |
| 215 | 214 |
| 216 void InstallTypedArray( | 215 void InstallTypedArray( |
| (...skipping 1128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1345 elements_kind); | 1344 elements_kind); |
| 1346 JSFunction::SetInitialMap(result, initial_map, | 1345 JSFunction::SetInitialMap(result, initial_map, |
| 1347 handle(initial_map->prototype(), isolate())); | 1346 handle(initial_map->prototype(), isolate())); |
| 1348 *fun = result; | 1347 *fun = result; |
| 1349 | 1348 |
| 1350 ElementsKind external_kind = GetNextTransitionElementsKind(elements_kind); | 1349 ElementsKind external_kind = GetNextTransitionElementsKind(elements_kind); |
| 1351 *external_map = Map::AsElementsKind(initial_map, external_kind); | 1350 *external_map = Map::AsElementsKind(initial_map, external_kind); |
| 1352 } | 1351 } |
| 1353 | 1352 |
| 1354 | 1353 |
| 1355 void Genesis::InitializeExperimentalGlobal() { | |
| 1356 // TODO(mstarzinger): Move this into Genesis::InitializeGlobal once we no | |
| 1357 // longer need to live behind flags, so functions get added to the snapshot. | |
| 1358 | |
| 1359 if (FLAG_harmony_generators) { | |
| 1360 // Create generator meta-objects and install them on the builtins object. | |
| 1361 Handle<JSObject> builtins(native_context()->builtins()); | |
| 1362 Handle<JSObject> generator_object_prototype = | |
| 1363 factory()->NewJSObject(isolate()->object_function(), TENURED); | |
| 1364 Handle<JSFunction> generator_function_prototype = InstallFunction( | |
| 1365 builtins, "GeneratorFunctionPrototype", JS_FUNCTION_TYPE, | |
| 1366 JSFunction::kHeaderSize, generator_object_prototype, | |
| 1367 Builtins::kIllegal); | |
| 1368 InstallFunction(builtins, "GeneratorFunction", | |
| 1369 JS_FUNCTION_TYPE, JSFunction::kSize, | |
| 1370 generator_function_prototype, Builtins::kIllegal); | |
| 1371 | |
| 1372 // Create maps for generator functions and their prototypes. Store those | |
| 1373 // maps in the native context. | |
| 1374 Handle<Map> sloppy_function_map(native_context()->sloppy_function_map()); | |
| 1375 Handle<Map> generator_function_map = Map::Copy(sloppy_function_map); | |
| 1376 generator_function_map->set_prototype(*generator_function_prototype); | |
| 1377 native_context()->set_sloppy_generator_function_map( | |
| 1378 *generator_function_map); | |
| 1379 | |
| 1380 // The "arguments" and "caller" instance properties aren't specified, so | |
| 1381 // technically we could leave them out. They make even less sense for | |
| 1382 // generators than for functions. Still, the same argument that it makes | |
| 1383 // sense to keep them around but poisoned in strict mode applies to | |
| 1384 // generators as well. With poisoned accessors, naive callers can still | |
| 1385 // iterate over the properties without accessing them. | |
| 1386 // | |
| 1387 // We can't use PoisonArgumentsAndCaller because that mutates accessor pairs | |
| 1388 // in place, and the initial state of the generator function map shares the | |
| 1389 // accessor pair with sloppy functions. Also the error message should be | |
| 1390 // different. Also unhappily, we can't use the API accessors to implement | |
| 1391 // poisoning, because API accessors present themselves as data properties, | |
| 1392 // not accessor properties, and so getOwnPropertyDescriptor raises an | |
| 1393 // exception as it tries to get the values. Sadness. | |
| 1394 Handle<AccessorPair> poison_pair(factory()->NewAccessorPair()); | |
| 1395 PropertyAttributes rw_attribs = | |
| 1396 static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE); | |
| 1397 Handle<JSFunction> poison_function = GetGeneratorPoisonFunction(); | |
| 1398 poison_pair->set_getter(*poison_function); | |
| 1399 poison_pair->set_setter(*poison_function); | |
| 1400 ReplaceAccessors(generator_function_map, factory()->arguments_string(), | |
| 1401 rw_attribs, poison_pair); | |
| 1402 ReplaceAccessors(generator_function_map, factory()->caller_string(), | |
| 1403 rw_attribs, poison_pair); | |
| 1404 | |
| 1405 Handle<Map> strict_function_map(native_context()->strict_function_map()); | |
| 1406 Handle<Map> strict_generator_function_map = Map::Copy(strict_function_map); | |
| 1407 // "arguments" and "caller" already poisoned. | |
| 1408 strict_generator_function_map->set_prototype(*generator_function_prototype); | |
| 1409 native_context()->set_strict_generator_function_map( | |
| 1410 *strict_generator_function_map); | |
| 1411 | |
| 1412 Handle<JSFunction> object_function(native_context()->object_function()); | |
| 1413 Handle<Map> generator_object_prototype_map = Map::Create( | |
| 1414 object_function, 0); | |
| 1415 generator_object_prototype_map->set_prototype( | |
| 1416 *generator_object_prototype); | |
| 1417 native_context()->set_generator_object_prototype_map( | |
| 1418 *generator_object_prototype_map); | |
| 1419 } | |
| 1420 } | |
| 1421 | |
| 1422 | |
| 1423 bool Genesis::CompileBuiltin(Isolate* isolate, int index) { | 1354 bool Genesis::CompileBuiltin(Isolate* isolate, int index) { |
| 1424 Vector<const char> name = Natives::GetScriptName(index); | 1355 Vector<const char> name = Natives::GetScriptName(index); |
| 1425 Handle<String> source_code = | 1356 Handle<String> source_code = |
| 1426 isolate->bootstrapper()->NativesSourceLookup(index); | 1357 isolate->bootstrapper()->NativesSourceLookup(index); |
| 1427 return CompileNative(isolate, name, source_code); | 1358 return CompileNative(isolate, name, source_code); |
| 1428 } | 1359 } |
| 1429 | 1360 |
| 1430 | 1361 |
| 1431 bool Genesis::CompileExperimentalBuiltin(Isolate* isolate, int index) { | 1362 bool Genesis::CompileExperimentalBuiltin(Isolate* isolate, int index) { |
| 1432 Vector<const char> name = ExperimentalNatives::GetScriptName(index); | 1363 Vector<const char> name = ExperimentalNatives::GetScriptName(index); |
| (...skipping 483 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1916 } | 1847 } |
| 1917 | 1848 |
| 1918 { // -- M a p I t e r a t o r | 1849 { // -- M a p I t e r a t o r |
| 1919 Handle<JSFunction> map_iterator_function = InstallFunction( | 1850 Handle<JSFunction> map_iterator_function = InstallFunction( |
| 1920 builtins, "MapIterator", JS_MAP_ITERATOR_TYPE, JSMapIterator::kSize, | 1851 builtins, "MapIterator", JS_MAP_ITERATOR_TYPE, JSMapIterator::kSize, |
| 1921 isolate()->initial_object_prototype(), Builtins::kIllegal); | 1852 isolate()->initial_object_prototype(), Builtins::kIllegal); |
| 1922 native_context()->set_map_iterator_map( | 1853 native_context()->set_map_iterator_map( |
| 1923 map_iterator_function->initial_map()); | 1854 map_iterator_function->initial_map()); |
| 1924 } | 1855 } |
| 1925 | 1856 |
| 1857 { |
| 1858 // Create generator meta-objects and install them on the builtins object. |
| 1859 Handle<JSObject> builtins(native_context()->builtins()); |
| 1860 Handle<JSObject> generator_object_prototype = |
| 1861 factory()->NewJSObject(isolate()->object_function(), TENURED); |
| 1862 Handle<JSFunction> generator_function_prototype = |
| 1863 InstallFunction(builtins, "GeneratorFunctionPrototype", |
| 1864 JS_FUNCTION_TYPE, JSFunction::kHeaderSize, |
| 1865 generator_object_prototype, Builtins::kIllegal); |
| 1866 InstallFunction(builtins, "GeneratorFunction", JS_FUNCTION_TYPE, |
| 1867 JSFunction::kSize, generator_function_prototype, |
| 1868 Builtins::kIllegal); |
| 1869 |
| 1870 // Create maps for generator functions and their prototypes. Store those |
| 1871 // maps in the native context. |
| 1872 Handle<Map> generator_function_map = |
| 1873 Map::Copy(sloppy_function_map_writable_prototype_); |
| 1874 generator_function_map->set_prototype(*generator_function_prototype); |
| 1875 native_context()->set_sloppy_generator_function_map( |
| 1876 *generator_function_map); |
| 1877 |
| 1878 // The "arguments" and "caller" instance properties aren't specified, so |
| 1879 // technically we could leave them out. They make even less sense for |
| 1880 // generators than for functions. Still, the same argument that it makes |
| 1881 // sense to keep them around but poisoned in strict mode applies to |
| 1882 // generators as well. With poisoned accessors, naive callers can still |
| 1883 // iterate over the properties without accessing them. |
| 1884 // |
| 1885 // We can't use PoisonArgumentsAndCaller because that mutates accessor pairs |
| 1886 // in place, and the initial state of the generator function map shares the |
| 1887 // accessor pair with sloppy functions. Also the error message should be |
| 1888 // different. Also unhappily, we can't use the API accessors to implement |
| 1889 // poisoning, because API accessors present themselves as data properties, |
| 1890 // not accessor properties, and so getOwnPropertyDescriptor raises an |
| 1891 // exception as it tries to get the values. Sadness. |
| 1892 Handle<AccessorPair> poison_pair(factory()->NewAccessorPair()); |
| 1893 PropertyAttributes rw_attribs = |
| 1894 static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE); |
| 1895 Handle<JSFunction> poison_function = GetGeneratorPoisonFunction(); |
| 1896 poison_pair->set_getter(*poison_function); |
| 1897 poison_pair->set_setter(*poison_function); |
| 1898 ReplaceAccessors(generator_function_map, factory()->arguments_string(), |
| 1899 rw_attribs, poison_pair); |
| 1900 ReplaceAccessors(generator_function_map, factory()->caller_string(), |
| 1901 rw_attribs, poison_pair); |
| 1902 |
| 1903 Handle<Map> strict_function_map(native_context()->strict_function_map()); |
| 1904 Handle<Map> strict_generator_function_map = Map::Copy(strict_function_map); |
| 1905 // "arguments" and "caller" already poisoned. |
| 1906 strict_generator_function_map->set_prototype(*generator_function_prototype); |
| 1907 native_context()->set_strict_generator_function_map( |
| 1908 *strict_generator_function_map); |
| 1909 |
| 1910 Handle<JSFunction> object_function(native_context()->object_function()); |
| 1911 Handle<Map> generator_object_prototype_map = |
| 1912 Map::Create(object_function, 0); |
| 1913 generator_object_prototype_map->set_prototype(*generator_object_prototype); |
| 1914 native_context()->set_generator_object_prototype_map( |
| 1915 *generator_object_prototype_map); |
| 1916 } |
| 1917 |
| 1926 if (FLAG_disable_native_files) { | 1918 if (FLAG_disable_native_files) { |
| 1927 PrintF("Warning: Running without installed natives!\n"); | 1919 PrintF("Warning: Running without installed natives!\n"); |
| 1928 return true; | 1920 return true; |
| 1929 } | 1921 } |
| 1930 | 1922 |
| 1931 // Install natives. | 1923 // Install natives. |
| 1932 for (int i = Natives::GetDebuggerCount(); | 1924 for (int i = Natives::GetDebuggerCount(); |
| 1933 i < Natives::GetBuiltinsCount(); | 1925 i < Natives::GetBuiltinsCount(); |
| 1934 i++) { | 1926 i++) { |
| 1935 if (!CompileBuiltin(isolate(), i)) return false; | 1927 if (!CompileBuiltin(isolate(), i)) return false; |
| (...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2089 "native " file) == 0) { \ | 2081 "native " file) == 0) { \ |
| 2090 if (!CompileExperimentalBuiltin(isolate(), i)) return false; \ | 2082 if (!CompileExperimentalBuiltin(isolate(), i)) return false; \ |
| 2091 } | 2083 } |
| 2092 | 2084 |
| 2093 | 2085 |
| 2094 bool Genesis::InstallExperimentalNatives() { | 2086 bool Genesis::InstallExperimentalNatives() { |
| 2095 for (int i = ExperimentalNatives::GetDebuggerCount(); | 2087 for (int i = ExperimentalNatives::GetDebuggerCount(); |
| 2096 i < ExperimentalNatives::GetBuiltinsCount(); | 2088 i < ExperimentalNatives::GetBuiltinsCount(); |
| 2097 i++) { | 2089 i++) { |
| 2098 INSTALL_EXPERIMENTAL_NATIVE(i, proxies, "proxy.js") | 2090 INSTALL_EXPERIMENTAL_NATIVE(i, proxies, "proxy.js") |
| 2099 INSTALL_EXPERIMENTAL_NATIVE(i, generators, "generator.js") | |
| 2100 INSTALL_EXPERIMENTAL_NATIVE(i, strings, "harmony-string.js") | 2091 INSTALL_EXPERIMENTAL_NATIVE(i, strings, "harmony-string.js") |
| 2101 INSTALL_EXPERIMENTAL_NATIVE(i, arrays, "harmony-array.js") | 2092 INSTALL_EXPERIMENTAL_NATIVE(i, arrays, "harmony-array.js") |
| 2102 INSTALL_EXPERIMENTAL_NATIVE(i, classes, "harmony-classes.js") | 2093 INSTALL_EXPERIMENTAL_NATIVE(i, classes, "harmony-classes.js") |
| 2103 } | 2094 } |
| 2104 | 2095 |
| 2105 InstallExperimentalNativeFunctions(); | 2096 InstallExperimentalNativeFunctions(); |
| 2106 return true; | 2097 return true; |
| 2107 } | 2098 } |
| 2108 | 2099 |
| 2109 | 2100 |
| (...skipping 540 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2650 InstallJSFunctionResultCaches(); | 2641 InstallJSFunctionResultCaches(); |
| 2651 InitializeNormalizedMapCaches(); | 2642 InitializeNormalizedMapCaches(); |
| 2652 if (!InstallNatives()) return; | 2643 if (!InstallNatives()) return; |
| 2653 | 2644 |
| 2654 MakeFunctionInstancePrototypeWritable(); | 2645 MakeFunctionInstancePrototypeWritable(); |
| 2655 | 2646 |
| 2656 if (!ConfigureGlobalObjects(global_proxy_template)) return; | 2647 if (!ConfigureGlobalObjects(global_proxy_template)) return; |
| 2657 isolate->counters()->contexts_created_from_scratch()->Increment(); | 2648 isolate->counters()->contexts_created_from_scratch()->Increment(); |
| 2658 } | 2649 } |
| 2659 | 2650 |
| 2660 // Initialize experimental globals and install experimental natives. | 2651 // Install experimental natives. |
| 2661 InitializeExperimentalGlobal(); | |
| 2662 if (!InstallExperimentalNatives()) return; | 2652 if (!InstallExperimentalNatives()) return; |
| 2663 | 2653 |
| 2664 // We can't (de-)serialize typed arrays currently, but we are lucky: The state | 2654 // We can't (de-)serialize typed arrays currently, but we are lucky: The state |
| 2665 // of the random number generator needs no initialization during snapshot | 2655 // of the random number generator needs no initialization during snapshot |
| 2666 // creation time and we don't need trigonometric functions then. | 2656 // creation time and we don't need trigonometric functions then. |
| 2667 if (!isolate->serializer_enabled()) { | 2657 if (!isolate->serializer_enabled()) { |
| 2668 // Initially seed the per-context random number generator using the | 2658 // Initially seed the per-context random number generator using the |
| 2669 // per-isolate random number generator. | 2659 // per-isolate random number generator. |
| 2670 const int num_elems = 2; | 2660 const int num_elems = 2; |
| 2671 const int num_bytes = num_elems * sizeof(uint32_t); | 2661 const int num_bytes = num_elems * sizeof(uint32_t); |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2725 return from + sizeof(NestingCounterType); | 2715 return from + sizeof(NestingCounterType); |
| 2726 } | 2716 } |
| 2727 | 2717 |
| 2728 | 2718 |
| 2729 // Called when the top-level V8 mutex is destroyed. | 2719 // Called when the top-level V8 mutex is destroyed. |
| 2730 void Bootstrapper::FreeThreadResources() { | 2720 void Bootstrapper::FreeThreadResources() { |
| 2731 DCHECK(!IsActive()); | 2721 DCHECK(!IsActive()); |
| 2732 } | 2722 } |
| 2733 | 2723 |
| 2734 } } // namespace v8::internal | 2724 } } // namespace v8::internal |
| OLD | NEW |