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}
This commit is contained in:
parent
e64810b5a5
commit
a44511d413
@ -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 <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) \
|
||||
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<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();
|
||||
}
|
||||
InitializeBuiltinTypedArrays();
|
||||
|
||||
result_ = native_context();
|
||||
}
|
||||
|
@ -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<FixedArray> array = factory->NewFixedArray(3);
|
||||
Handle<HeapNumber> y0 = factory->NewHeapNumber(y[0]);
|
||||
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);
|
||||
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<double*>(backing_store);
|
||||
return Smi::FromInt(fdlibm::rempio2(x, y));
|
||||
}
|
||||
|
||||
|
||||
|
@ -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) \
|
||||
|
10
src/third_party/fdlibm/fdlibm.cc
vendored
10
src/third_party/fdlibm/fdlibm.cc
vendored
@ -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<double>(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<double>(static_cast<int32_t>(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];
|
||||
|
11
src/third_party/fdlibm/fdlibm.js
vendored
11
src/third_party/fdlibm/fdlibm.js
vendored
@ -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
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user