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 |