Allocate typed array for rempio2 result.
authoryangguo <yangguo@chromium.org>
Fri, 6 Feb 2015 09:54:58 +0000 (01:54 -0800)
committerCommit bot <commit-bot@chromium.org>
Fri, 6 Feb 2015 09:55:07 +0000 (09:55 +0000)
R=svenpanne@chromium.org
BUG=chromium:441896
LOG=N

Review URL: https://codereview.chromium.org/866553003

Cr-Commit-Position: refs/heads/master@{#26482}

src/bootstrapper.cc
src/runtime/runtime-maths.cc
src/runtime/runtime.h
src/third_party/fdlibm/fdlibm.cc
src/third_party/fdlibm/fdlibm.js

index 134b924..6c479c6 100644 (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();
 }
index 6397ad1..68dfa49 100644 (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));
 }
 
 
index 4c3752b..e8f8295 100644 (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)                      \
index 90099f1..b8bc243 100644 (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];
index ceeacc5..8804469 100644 (file)
 // 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