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:
yangguo 2015-02-06 01:54:58 -08:00 committed by Commit bot
parent e64810b5a5
commit a44511d413
5 changed files with 78 additions and 62 deletions

View File

@ -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();
}

View File

@ -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));
}

View File

@ -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) \

View File

@ -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];

View File

@ -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