Commit a44511d4 authored by yangguo's avatar yangguo Committed by Commit bot

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}
parent e64810b5
...@@ -211,6 +211,8 @@ class Genesis BASE_EMBEDDED { ...@@ -211,6 +211,8 @@ class Genesis BASE_EMBEDDED {
// Used for creating a context from scratch. // Used for creating a context from scratch.
void InstallNativeFunctions(); void InstallNativeFunctions();
void InstallExperimentalNativeFunctions(); void InstallExperimentalNativeFunctions();
// Typed arrays are not serializable and have to initialized afterwards.
void InitializeBuiltinTypedArrays();
#define DECLARE_FEATURE_INITIALIZATION(id, descr) \ #define DECLARE_FEATURE_INITIALIZATION(id, descr) \
void InstallNativeFunctions_##id(); \ void InstallNativeFunctions_##id(); \
...@@ -1579,6 +1581,60 @@ void Genesis::InstallExperimentalNativeFunctions() { ...@@ -1579,6 +1581,60 @@ void Genesis::InstallExperimentalNativeFunctions() {
} }
template <typename Data>
Data* SetBuiltinTypedArray(Isolate* isolate, Handle<JSBuiltinsObject> builtins,
ExternalArrayType type, Data* data,
size_t num_elements, const char* name) {
size_t byte_length = num_elements * sizeof(*data);
Handle<JSArrayBuffer> buffer = isolate->factory()->NewJSArrayBuffer();
bool should_be_freed = false;
if (data == NULL) {
data = reinterpret_cast<Data*>(malloc(byte_length));
should_be_freed = true;
}
Runtime::SetupArrayBuffer(isolate, buffer, true, data, byte_length);
buffer->set_should_be_freed(should_be_freed);
Handle<JSTypedArray> typed_array =
isolate->factory()->NewJSTypedArray(type, buffer, 0, num_elements);
Handle<String> 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<JSBuiltinsObject> 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<uint32_t>(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<double*>(fdlibm::MathConstants::constants);
SetBuiltinTypedArray<double>(isolate(), builtins, kExternalFloat64Array,
data, num_elements, "kMath");
}
{ // Initialize a result array for rempio2 calculation
const size_t num_elements = 2;
SetBuiltinTypedArray<double>(isolate(), builtins, kExternalFloat64Array,
NULL, num_elements, "rempio2result");
}
}
#define EMPTY_NATIVE_FUNCTIONS_FOR_FEATURE(id) \ #define EMPTY_NATIVE_FUNCTIONS_FOR_FEATURE(id) \
void Genesis::InstallNativeFunctions_##id() {} void Genesis::InstallNativeFunctions_##id() {}
...@@ -2816,46 +2872,7 @@ Genesis::Genesis(Isolate* isolate, ...@@ -2816,46 +2872,7 @@ Genesis::Genesis(Isolate* isolate,
// The serializer cannot serialize typed arrays. Reset those typed arrays // The serializer cannot serialize typed arrays. Reset those typed arrays
// for each new context. // for each new context.
{ InitializeBuiltinTypedArrays();
// 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<uint32_t*>(malloc(num_bytes));
do {
isolate->random_number_generator()->NextBytes(state, num_bytes);
} while (state[0] == 0 || state[1] == 0);
v8::Local<v8::ArrayBuffer> buffer = v8::ArrayBuffer::New(
reinterpret_cast<v8::Isolate*>(isolate), state, num_bytes);
Utils::OpenHandle(*buffer)->set_should_be_freed(true);
v8::Local<v8::Uint32Array> ta = v8::Uint32Array::New(buffer, 0, num_elems);
Handle<JSBuiltinsObject> builtins(native_context()->builtins());
Handle<String> 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<v8::ArrayBuffer> trig_buffer = v8::ArrayBuffer::New(
reinterpret_cast<v8::Isolate*>(isolate),
const_cast<double*>(fdlibm::MathConstants::constants), table_num_bytes);
v8::Local<v8::Float64Array> trig_table =
v8::Float64Array::New(trig_buffer, 0, constants_size);
Handle<String> 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();
}
result_ = native_context(); result_ = native_context();
} }
......
...@@ -60,19 +60,15 @@ RUNTIME_FUNCTION(Runtime_ConstructDouble) { ...@@ -60,19 +60,15 @@ RUNTIME_FUNCTION(Runtime_ConstructDouble) {
RUNTIME_FUNCTION(Runtime_RemPiO2) { RUNTIME_FUNCTION(Runtime_RemPiO2) {
HandleScope handle_scope(isolate); SealHandleScope shs(isolate);
DCHECK(args.length() == 1); DisallowHeapAllocation no_gc;
DCHECK(args.length() == 2);
CONVERT_DOUBLE_ARG_CHECKED(x, 0); CONVERT_DOUBLE_ARG_CHECKED(x, 0);
Factory* factory = isolate->factory(); CONVERT_ARG_CHECKED(JSTypedArray, result, 1);
double y[2] = {0.0, 0.0}; RUNTIME_ASSERT(result->byte_length() == Smi::FromInt(2 * sizeof(double)));
int n = fdlibm::rempio2(x, y); void* backing_store = JSArrayBuffer::cast(result->buffer())->backing_store();
Handle<FixedArray> array = factory->NewFixedArray(3); double* y = static_cast<double*>(backing_store);
Handle<HeapNumber> y0 = factory->NewHeapNumber(y[0]); return Smi::FromInt(fdlibm::rempio2(x, y));
Handle<HeapNumber> y1 = factory->NewHeapNumber(y[1]);
array->set(0, Smi::FromInt(n));
array->set(1, *y0);
array->set(2, *y1);
return *factory->NewJSArrayWithElements(array);
} }
......
...@@ -152,7 +152,7 @@ namespace internal { ...@@ -152,7 +152,7 @@ namespace internal {
F(MathExpRT, 1, 1) \ F(MathExpRT, 1, 1) \
F(RoundNumber, 1, 1) \ F(RoundNumber, 1, 1) \
F(MathFround, 1, 1) \ F(MathFround, 1, 1) \
F(RemPiO2, 1, 1) \ F(RemPiO2, 2, 1) \
\ \
/* Regular expressions */ \ /* Regular expressions */ \
F(RegExpInitializeAndCompile, 3, 1) \ F(RegExpInitializeAndCompile, 3, 1) \
......
...@@ -126,7 +126,7 @@ static const double PIo2[] = { ...@@ -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; static const int32_t jk = 3;
double fw; double fw;
int32_t jx = nx - 1; int32_t jx = nx - 1;
...@@ -135,12 +135,12 @@ int __kernel_rem_pio2(double* x, double* y, int e0, int nx) { ...@@ -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 q0 = e0 - 24 * (jv + 1);
int32_t m = jx + jk; int32_t m = jx + jk;
double f[10]; double f[20];
for (int i = 0, j = jv - jx; i <= m; i++, j++) { for (int i = 0, j = jv - jx; i <= m; i++, j++) {
f[i] = (j < 0) ? zero : static_cast<double>(two_over_pi[j]); f[i] = (j < 0) ? zero : static_cast<double>(two_over_pi[j]);
} }
double q[10]; double q[20];
for (int i = 0; i <= jk; i++) { for (int i = 0; i <= jk; i++) {
fw = 0.0; fw = 0.0;
for (int j = 0; j <= jx; j++) fw += x[j] * f[jx + i - j]; 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) { ...@@ -151,7 +151,7 @@ int __kernel_rem_pio2(double* x, double* y, int e0, int nx) {
recompute: recompute:
int32_t iq[10]; int32_t iq[20];
double z = q[jz]; double z = q[jz];
for (int i = 0, j = jz; j > 0; i++, j--) { for (int i = 0, j = jz; j > 0; i++, j--) {
fw = static_cast<double>(static_cast<int32_t>(twon24 * z)); fw = static_cast<double>(static_cast<int32_t>(twon24 * z));
...@@ -242,7 +242,7 @@ recompute: ...@@ -242,7 +242,7 @@ recompute:
fw *= twon24; fw *= twon24;
} }
double fq[10]; double fq[20];
for (int i = jz; i >= 0; i--) { for (int i = jz; i >= 0; i--) {
fw = 0.0; fw = 0.0;
for (int k = 0; k <= jk && k <= jz - i; k++) fw += PIo2[k] * q[i + k]; for (int k = 0; k <= jk && k <= jz - i; k++) fw += PIo2[k] * q[i + k];
......
...@@ -20,10 +20,13 @@ ...@@ -20,10 +20,13 @@
// and exposed through kMath as typed array. We assume the compiler to convert // and exposed through kMath as typed array. We assume the compiler to convert
// from decimal to binary accurately enough to produce the intended values. // from decimal to binary accurately enough to produce the intended values.
// kMath is initialized to a Float64Array during genesis and not writable. // 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"; "use strict";
var kMath; var kMath;
var rempio2result;
const INVPIO2 = kMath[0]; const INVPIO2 = kMath[0];
const PIO2_1 = kMath[1]; const PIO2_1 = kMath[1];
...@@ -38,6 +41,7 @@ const PIO4LO = kMath[33]; ...@@ -38,6 +41,7 @@ const PIO4LO = kMath[33];
// Compute k and r such that x - k*pi/2 = r where |r| < pi/4. For // 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 // precision, r is returned as two values y0 and y1 such that r = y0 + y1
// to more than double precision. // to more than double precision.
macro REMPIO2(X) macro REMPIO2(X)
var n, y0, y1; var n, y0, y1;
var hx = %_DoubleHi(X); var hx = %_DoubleHi(X);
...@@ -105,10 +109,9 @@ macro REMPIO2(X) ...@@ -105,10 +109,9 @@ macro REMPIO2(X)
} }
} else { } else {
// Need to do full Payne-Hanek reduction here. // Need to do full Payne-Hanek reduction here.
var r = %RemPiO2(X); n = %RemPiO2(X, rempio2result);
n = r[0]; y0 = rempio2result[0];
y0 = r[1]; y1 = rempio2result[1];
y1 = r[2];
} }
endmacro endmacro
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment