diff --git a/src/bootstrapper.cc b/src/bootstrapper.cc index 6699dacd12..363fa8a23c 100644 --- a/src/bootstrapper.cc +++ b/src/bootstrapper.cc @@ -199,7 +199,7 @@ class Genesis BASE_EMBEDDED { ContextType context_type); void InitializeExperimentalGlobal(); // Typed arrays are not serializable and have to initialized afterwards. - void InitializeBuiltinTypedArrays(); + bool InitializeBuiltinTypedArrays(); // Depending on the situation, expose and/or get rid of the utils object. void ConfigureUtilsObject(ContextType context_type); @@ -1791,42 +1791,36 @@ static Handle ResolveBuiltinIdHolder(Handle native_context, template -Data* SetBuiltinTypedArray(Isolate* isolate, Handle builtins, - ExternalArrayType type, Data* data, - size_t num_elements, const char* name, - const SharedFlag shared = SharedFlag::kNotShared, - const PretenureFlag pretenure = TENURED) { - size_t byte_length = num_elements * sizeof(*data); +Handle CreateTypedArray(Isolate* isolate, ExternalArrayType type, + size_t num_elements, Data** data) { + size_t byte_length = num_elements * sizeof(**data); Handle buffer = - isolate->factory()->NewJSArrayBuffer(shared, pretenure); - bool is_external = data != nullptr; + isolate->factory()->NewJSArrayBuffer(SharedFlag::kNotShared, TENURED); + bool is_external = (*data != nullptr); if (!is_external) { - data = reinterpret_cast( + *data = reinterpret_cast( isolate->array_buffer_allocator()->Allocate(byte_length)); } - JSArrayBuffer::Setup(buffer, isolate, is_external, data, byte_length, shared); - - Handle typed_array = isolate->factory()->NewJSTypedArray( - type, buffer, 0, num_elements, pretenure); - Handle name_string = isolate->factory()->InternalizeUtf8String(name); - // Reset property cell type before (re)initializing. - JSBuiltinsObject::InvalidatePropertyCell(builtins, name_string); - JSObject::SetOwnPropertyIgnoreAttributes(builtins, name_string, typed_array, - FROZEN) - .Assert(); - return data; + JSArrayBuffer::Setup(buffer, isolate, is_external, *data, byte_length, + SharedFlag::kNotShared); + return isolate->factory()->NewJSTypedArray(type, buffer, 0, num_elements, + TENURED); } -void Genesis::InitializeBuiltinTypedArrays() { - Handle builtins(native_context()->builtins()); - { // Initially seed the per-context random number generator using the - // per-isolate random number generator. +bool Genesis::InitializeBuiltinTypedArrays() { + HandleScope scope(isolate()); + Handle rng_state; + Handle math_constants; + Handle rempio2result; + + { + // Seed the per-context RNG using the per-isolate RNG. const size_t num_elements = 2; const size_t num_bytes = num_elements * sizeof(uint32_t); - uint32_t* state = SetBuiltinTypedArray(isolate(), builtins, - kExternalUint32Array, NULL, - num_elements, "rngstate"); + uint32_t* state = NULL; + rng_state = + CreateTypedArray(isolate(), kExternalUint32Array, num_elements, &state); do { isolate()->random_number_generator()->NextBytes(state, num_bytes); } while (state[0] == 0 || state[1] == 0); @@ -1834,18 +1828,28 @@ void Genesis::InitializeBuiltinTypedArrays() { { // Initialize trigonometric lookup tables and constants. const size_t num_elements = arraysize(fdlibm::MathConstants::constants); - double* data = const_cast(fdlibm::MathConstants::constants); - SetBuiltinTypedArray(isolate(), builtins, kExternalFloat64Array, - data, num_elements, "kMath"); + double* constants = const_cast(fdlibm::MathConstants::constants); + math_constants = CreateTypedArray(isolate(), kExternalFloat64Array, + num_elements, &constants); } { // Initialize a result array for rempio2 calculation const size_t num_elements = 2; - double* data = - SetBuiltinTypedArray(isolate(), builtins, kExternalFloat64Array, - NULL, num_elements, "rempio2result"); + double* data = NULL; + rempio2result = + CreateTypedArray(isolate(), kExternalFloat64Array, num_elements, &data); for (size_t i = 0; i < num_elements; i++) data[i] = 0; } + + Handle utils = + Handle::cast(isolate()->natives_utils_object()); + Handle name_string = isolate()->factory()->NewStringFromAsciiChecked( + "InitializeBuiltinTypedArrays"); + Handle fun = JSObject::GetDataProperty(utils, name_string); + Handle receiver = isolate()->factory()->undefined_value(); + Handle args[] = {utils, rng_state, math_constants, rempio2result}; + return !Execution::Call(isolate(), fun, receiver, arraysize(args), args) + .is_null(); } @@ -3270,6 +3274,7 @@ Genesis::Genesis(Isolate* isolate, // snapshot as we should be able to turn them off at runtime. Re-installing // them after they have already been deserialized would also fail. if (context_type == FULL_CONTEXT) { + if (!InitializeBuiltinTypedArrays()) return; if (!isolate->serializer_enabled()) { InitializeExperimentalGlobal(); if (!InstallExperimentalNatives()) return; @@ -3280,9 +3285,9 @@ Genesis::Genesis(Isolate* isolate, } // The serializer cannot serialize typed arrays. Reset those typed arrays // for each new context. - InitializeBuiltinTypedArrays(); } else if (context_type == DEBUG_CONTEXT) { DCHECK(!isolate->serializer_enabled()); + if (!InitializeBuiltinTypedArrays()) return; InitializeExperimentalGlobal(); if (!InstallDebuggerNatives()) return; } diff --git a/src/js/math.js b/src/js/math.js index 071566ff01..4d0b1f7282 100644 --- a/src/js/math.js +++ b/src/js/math.js @@ -2,8 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -var rngstate; // Initialized to a Uint32Array during genesis. - (function(global, utils) { "use strict"; @@ -16,8 +14,13 @@ var GlobalMath = global.Math; var GlobalObject = global.Object; var InternalArray = utils.InternalArray; var NaN = %GetRootNaN(); +var rngstate; var toStringTagSymbol = utils.ImportNow("to_string_tag_symbol"); +utils.SetupTypedArray(function(arg1, arg2, arg3) { + rngstate = arg1; +}); + //------------------------------------------------------------------- // ECMA 262 - 15.8.2.1 diff --git a/src/js/prologue.js b/src/js/prologue.js index 34de8a7d20..4b4e36c79e 100644 --- a/src/js/prologue.js +++ b/src/js/prologue.js @@ -14,6 +14,14 @@ var imports = UNDEFINED; var imports_from_experimental = UNDEFINED; var exports_container = %ExportFromRuntime({}); +var typed_array_setup = UNDEFINED; + +// Register context value to be initialized with a typed array in +// Genesis::InitializeBuiltinTypedArrays. +function SetupTypedArray(f) { + f.next = typed_array_setup; + typed_array_setup = f; +} // Export to other scripts. // In normal natives, this exports functions to other normal natives. @@ -240,6 +248,9 @@ function PostExperimentals(utils) { utils.Export = UNDEFINED; utils.PostDebug = UNDEFINED; utils.PostExperimentals = UNDEFINED; + utils.InitializeBuiltinTypedArrays = UNDEFINED; + utils.SetupTypedArray = UNDEFINED; + typed_array_setup = UNDEFINED; } @@ -255,12 +266,25 @@ function PostDebug(utils) { utils.ImportNow = UNDEFINED; utils.PostDebug = UNDEFINED; utils.PostExperimentals = UNDEFINED; + utils.InitializeBuiltinTypedArrays = UNDEFINED; + utils.SetupTypedArray = UNDEFINED; + typed_array_setup = UNDEFINED; +} + + +function InitializeBuiltinTypedArrays( + utils, rng_state, math_constants, rempio2result) { + var setup_list = typed_array_setup; + + for ( ; !IS_UNDEFINED(setup_list); setup_list = setup_list.next) { + setup_list(rng_state, math_constants, rempio2result); + } } // ----------------------------------------------------------------------- -%OptimizeObjectForAddingMultipleProperties(utils, 13); +%OptimizeObjectForAddingMultipleProperties(utils, 15); utils.Import = Import; utils.ImportNow = ImportNow; @@ -275,6 +299,8 @@ utils.SetUpLockedPrototype = SetUpLockedPrototype; utils.PostNatives = PostNatives; utils.PostExperimentals = PostExperimentals; utils.PostDebug = PostDebug; +utils.SetupTypedArray = SetupTypedArray; +utils.InitializeBuiltinTypedArrays = InitializeBuiltinTypedArrays; %ToFastProperties(utils); diff --git a/src/third_party/fdlibm/fdlibm.js b/src/third_party/fdlibm/fdlibm.js index 983a86c151..1cc73b84a9 100644 --- a/src/third_party/fdlibm/fdlibm.js +++ b/src/third_party/fdlibm/fdlibm.js @@ -23,9 +23,6 @@ // rempio2result is used as a container for return values of %RemPiO2. It is // initialized to a two-element Float64Array during genesis. -var kMath; -var rempio2result; - (function(global, utils) { "use strict"; @@ -36,15 +33,22 @@ var rempio2result; // Imports var GlobalMath = global.Math; +var kMath; var MathAbs; var MathExp; var NaN = %GetRootNaN(); +var rempio2result; utils.Import(function(from) { MathAbs = from.MathAbs; MathExp = from.MathExp; }); +utils.SetupTypedArray(function(arg1, arg2, arg3) { + kMath = arg2; + rempio2result = arg3; +}); + // ------------------------------------------------------------------- define INVPIO2 = kMath[0];