From: yangguo Date: Fri, 6 Feb 2015 09:54:58 +0000 (-0800) Subject: Allocate typed array for rempio2 result. X-Git-Tag: upstream/4.7.83~4558 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=a44511d4131c74c6a0f9622af9ccaab83a5235bc;p=platform%2Fupstream%2Fv8.git Allocate typed array for rempio2 result. R=svenpanne@chromium.org BUG=chromium:441896 LOG=N Review URL: https://codereview.chromium.org/866553003 Cr-Commit-Position: refs/heads/master@{#26482} --- diff --git a/src/bootstrapper.cc b/src/bootstrapper.cc index 134b924ee..6c479c6c8 100644 --- a/src/bootstrapper.cc +++ b/src/bootstrapper.cc @@ -211,6 +211,8 @@ class Genesis BASE_EMBEDDED { // Used for creating a context from scratch. void InstallNativeFunctions(); void InstallExperimentalNativeFunctions(); + // Typed arrays are not serializable and have to initialized afterwards. + void InitializeBuiltinTypedArrays(); #define DECLARE_FEATURE_INITIALIZATION(id, descr) \ void InstallNativeFunctions_##id(); \ @@ -1579,6 +1581,60 @@ void Genesis::InstallExperimentalNativeFunctions() { } +template +Data* SetBuiltinTypedArray(Isolate* isolate, Handle builtins, + ExternalArrayType type, Data* data, + size_t num_elements, const char* name) { + size_t byte_length = num_elements * sizeof(*data); + Handle buffer = isolate->factory()->NewJSArrayBuffer(); + bool should_be_freed = false; + if (data == NULL) { + data = reinterpret_cast(malloc(byte_length)); + should_be_freed = true; + } + Runtime::SetupArrayBuffer(isolate, buffer, true, data, byte_length); + buffer->set_should_be_freed(should_be_freed); + + Handle typed_array = + isolate->factory()->NewJSTypedArray(type, buffer, 0, num_elements); + 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, + DONT_DELETE).Assert(); + return data; +} + + +void Genesis::InitializeBuiltinTypedArrays() { + Handle builtins(native_context()->builtins()); + { // Initially seed the per-context random number generator using the + // per-isolate random number generator. + 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"); + do { + isolate()->random_number_generator()->NextBytes(state, num_bytes); + } while (state[0] == 0 || state[1] == 0); + } + + { // 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"); + } + + { // Initialize a result array for rempio2 calculation + const size_t num_elements = 2; + SetBuiltinTypedArray(isolate(), builtins, kExternalFloat64Array, + NULL, num_elements, "rempio2result"); + } +} + + #define EMPTY_NATIVE_FUNCTIONS_FOR_FEATURE(id) \ void Genesis::InstallNativeFunctions_##id() {} @@ -2816,46 +2872,7 @@ Genesis::Genesis(Isolate* isolate, // The serializer cannot serialize typed arrays. Reset those typed arrays // for each new context. - { - // Initially seed the per-context random number generator using the - // per-isolate random number generator. - const int num_elems = 2; - const int num_bytes = num_elems * sizeof(uint32_t); - uint32_t* state = reinterpret_cast(malloc(num_bytes)); - - do { - isolate->random_number_generator()->NextBytes(state, num_bytes); - } while (state[0] == 0 || state[1] == 0); - - v8::Local buffer = v8::ArrayBuffer::New( - reinterpret_cast(isolate), state, num_bytes); - Utils::OpenHandle(*buffer)->set_should_be_freed(true); - v8::Local ta = v8::Uint32Array::New(buffer, 0, num_elems); - Handle builtins(native_context()->builtins()); - - Handle rngstate = - factory()->InternalizeOneByteString(STATIC_CHAR_VECTOR("rngstate")); - // Reset property cell type before (re)initializing. - JSBuiltinsObject::InvalidatePropertyCell(builtins, rngstate); - JSObject::SetOwnPropertyIgnoreAttributes( - builtins, rngstate, Utils::OpenHandle(*ta), DONT_DELETE).Assert(); - - // Initialize trigonometric lookup tables and constants. - const int constants_size = arraysize(fdlibm::MathConstants::constants); - const int table_num_bytes = constants_size * kDoubleSize; - v8::Local trig_buffer = v8::ArrayBuffer::New( - reinterpret_cast(isolate), - const_cast(fdlibm::MathConstants::constants), table_num_bytes); - v8::Local trig_table = - v8::Float64Array::New(trig_buffer, 0, constants_size); - - Handle kmath = - factory()->InternalizeOneByteString(STATIC_CHAR_VECTOR("kMath")); - // Reset property cell type before (re)initializing. - JSBuiltinsObject::InvalidatePropertyCell(builtins, kmath); - JSObject::SetOwnPropertyIgnoreAttributes( - builtins, kmath, Utils::OpenHandle(*trig_table), DONT_DELETE).Assert(); - } + InitializeBuiltinTypedArrays(); result_ = native_context(); } diff --git a/src/runtime/runtime-maths.cc b/src/runtime/runtime-maths.cc index 6397ad15d..68dfa49af 100644 --- a/src/runtime/runtime-maths.cc +++ b/src/runtime/runtime-maths.cc @@ -60,19 +60,15 @@ RUNTIME_FUNCTION(Runtime_ConstructDouble) { RUNTIME_FUNCTION(Runtime_RemPiO2) { - HandleScope handle_scope(isolate); - DCHECK(args.length() == 1); + SealHandleScope shs(isolate); + DisallowHeapAllocation no_gc; + DCHECK(args.length() == 2); CONVERT_DOUBLE_ARG_CHECKED(x, 0); - Factory* factory = isolate->factory(); - double y[2] = {0.0, 0.0}; - int n = fdlibm::rempio2(x, y); - Handle array = factory->NewFixedArray(3); - Handle y0 = factory->NewHeapNumber(y[0]); - Handle y1 = factory->NewHeapNumber(y[1]); - array->set(0, Smi::FromInt(n)); - array->set(1, *y0); - array->set(2, *y1); - return *factory->NewJSArrayWithElements(array); + CONVERT_ARG_CHECKED(JSTypedArray, result, 1); + RUNTIME_ASSERT(result->byte_length() == Smi::FromInt(2 * sizeof(double))); + void* backing_store = JSArrayBuffer::cast(result->buffer())->backing_store(); + double* y = static_cast(backing_store); + return Smi::FromInt(fdlibm::rempio2(x, y)); } diff --git a/src/runtime/runtime.h b/src/runtime/runtime.h index 4c3752b4a..e8f8295bf 100644 --- a/src/runtime/runtime.h +++ b/src/runtime/runtime.h @@ -152,7 +152,7 @@ namespace internal { F(MathExpRT, 1, 1) \ F(RoundNumber, 1, 1) \ F(MathFround, 1, 1) \ - F(RemPiO2, 1, 1) \ + F(RemPiO2, 2, 1) \ \ /* Regular expressions */ \ F(RegExpInitializeAndCompile, 3, 1) \ diff --git a/src/third_party/fdlibm/fdlibm.cc b/src/third_party/fdlibm/fdlibm.cc index 90099f141..b8bc243f4 100644 --- a/src/third_party/fdlibm/fdlibm.cc +++ b/src/third_party/fdlibm/fdlibm.cc @@ -126,7 +126,7 @@ static const double PIo2[] = { }; -int __kernel_rem_pio2(double* x, double* y, int e0, int nx) { +INLINE(int __kernel_rem_pio2(double* x, double* y, int e0, int nx)) { static const int32_t jk = 3; double fw; int32_t jx = nx - 1; @@ -135,12 +135,12 @@ int __kernel_rem_pio2(double* x, double* y, int e0, int nx) { int32_t q0 = e0 - 24 * (jv + 1); int32_t m = jx + jk; - double f[10]; + double f[20]; for (int i = 0, j = jv - jx; i <= m; i++, j++) { f[i] = (j < 0) ? zero : static_cast(two_over_pi[j]); } - double q[10]; + double q[20]; for (int i = 0; i <= jk; i++) { fw = 0.0; for (int j = 0; j <= jx; j++) fw += x[j] * f[jx + i - j]; @@ -151,7 +151,7 @@ int __kernel_rem_pio2(double* x, double* y, int e0, int nx) { recompute: - int32_t iq[10]; + int32_t iq[20]; double z = q[jz]; for (int i = 0, j = jz; j > 0; i++, j--) { fw = static_cast(static_cast(twon24 * z)); @@ -242,7 +242,7 @@ recompute: fw *= twon24; } - double fq[10]; + double fq[20]; for (int i = jz; i >= 0; i--) { fw = 0.0; for (int k = 0; k <= jk && k <= jz - i; k++) fw += PIo2[k] * q[i + k]; diff --git a/src/third_party/fdlibm/fdlibm.js b/src/third_party/fdlibm/fdlibm.js index ceeacc59b..880446990 100644 --- a/src/third_party/fdlibm/fdlibm.js +++ b/src/third_party/fdlibm/fdlibm.js @@ -20,10 +20,13 @@ // and exposed through kMath as typed array. We assume the compiler to convert // from decimal to binary accurately enough to produce the intended values. // kMath is initialized to a Float64Array during genesis and not writable. +// rempio2result is used as a container for return values of %RemPiO2. It is +// initialized to a two-element Float64Array during genesis. "use strict"; var kMath; +var rempio2result; const INVPIO2 = kMath[0]; const PIO2_1 = kMath[1]; @@ -38,6 +41,7 @@ const PIO4LO = kMath[33]; // Compute k and r such that x - k*pi/2 = r where |r| < pi/4. For // precision, r is returned as two values y0 and y1 such that r = y0 + y1 // to more than double precision. + macro REMPIO2(X) var n, y0, y1; var hx = %_DoubleHi(X); @@ -105,10 +109,9 @@ macro REMPIO2(X) } } else { // Need to do full Payne-Hanek reduction here. - var r = %RemPiO2(X); - n = r[0]; - y0 = r[1]; - y1 = r[2]; + n = %RemPiO2(X, rempio2result); + y0 = rempio2result[0]; + y1 = rempio2result[1]; } endmacro