Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1223)

Unified Diff: src/elements.cc

Issue 2735563002: Migrate %TypedArray%.prototype.fill to C++ (Closed)
Patch Set: format 80 cols Created 3 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: src/elements.cc
diff --git a/src/elements.cc b/src/elements.cc
index 7b7f6893d84b557224acb1232b7798eb39cbb461..b36ed4f276593a544292db9035e62575aa46a7de 100644
--- a/src/elements.cc
+++ b/src/elements.cc
@@ -470,6 +470,23 @@ static void SortIndices(
}
}
+static Object* FillNumberSlowPath(Isolate* isolate, Handle<JSTypedArray> array,
+ Handle<Object> obj_value,
+ uint32_t start, uint32_t end) {
+ const char* kMethodName = "%TypedArray%.prototype.fill";
+ Handle<Object> cast_value;
+ ElementsAccessor* elements = array->GetElementsAccessor();
+
+ for (uint32_t k = start; k < end; ++k) {
+ ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
+ isolate, cast_value, Object::ToNumber(obj_value));
+ // TODO(caitp,cbruni): throw on neutered array
+ if (V8_UNLIKELY(array->WasNeutered())) return *array;
+ elements->Set(array, k, *cast_value);
+ }
+ return *array;
+}
+
static Maybe<bool> IncludesValueSlowPath(Isolate* isolate,
Handle<JSObject> receiver,
Handle<Object> value,
@@ -1191,6 +1208,17 @@ class ElementsAccessorBase : public ElementsAccessor {
return Subclass::GetCapacityImpl(holder, backing_store);
}
+ static Object* FillImpl(Isolate* isolate, Handle<JSObject> receiver,
+ Handle<Object> obj_value, uint32_t start, uint32_t end) {
+ UNREACHABLE();
+ return *receiver;
+ }
+
+ Object* Fill(Isolate* isolate, Handle<JSObject> receiver,
+ Handle<Object> obj_value, uint32_t start, uint32_t end) {
+ return Subclass::FillImpl(isolate, receiver, obj_value, start, end);
+ }
+
static Maybe<bool> IncludesValueImpl(Isolate* isolate,
Handle<JSObject> receiver,
Handle<Object> value,
@@ -2815,6 +2843,58 @@ class TypedElementsAccessor
return Just(true);
}
+ template <typename T, ElementsKind K = Kind>
+ static inline uint8_t MaybeClamp(
Camillo Bruni 2017/03/14 09:30:35 ConvertNumberToUint8Clamped(Handle<Object> obj_val
rongjie 2017/03/14 10:08:48 Done.
+ Handle<Object> obj_value, JSTypedArray* array,
+ typename std::enable_if<K == UINT8_CLAMPED_ELEMENTS, T>::type = 0) {
+ double value = 0.0;
+ if (obj_value->IsSmi()) {
+ value = Smi::cast(*obj_value)->value();
Camillo Bruni 2017/03/14 09:30:36 Special case directly on Smi and avoid slow double
rongjie 2017/03/14 10:08:48 Done.
+ } else {
+ DCHECK(obj_value->IsHeapNumber());
+ value = HeapNumber::cast(*obj_value)->value();
+ }
+ value = std::min<double>(std::max<double>(0, value), 255);
+ return static_cast<uint8_t>(value);
+ }
+
+ template <typename T, ElementsKind K = Kind>
+ static inline T MaybeClamp(
Camillo Bruni 2017/03/14 09:30:36 static ctype ConvertToNumber(Handle<Object> obj_va
Camillo Bruni 2017/03/14 09:31:21 On 2017/03/14 at 09:30:36, Camillo Bruni wrote: >
rongjie 2017/03/14 10:08:47 Done.
+ Handle<Object> obj_value, JSTypedArray* array,
+ typename std::enable_if<K != UINT8_CLAMPED_ELEMENTS, T>::type = 0) {
+ T value = 0;
Camillo Bruni 2017/03/14 09:30:36 ctype value = 0;
rongjie 2017/03/14 10:08:48 Done.
+ if (obj_value->IsSmi()) {
+ value = static_cast<T>(Smi::cast(*obj_value)->value());
+ } else {
+ DCHECK(obj_value->IsHeapNumber());
+ value = static_cast<T>(HeapNumber::cast(*obj_value)->value());
+ }
+ return value;
+ }
+
+ static Object* FillImpl(Isolate* isolate, Handle<JSObject> receiver,
+ Handle<Object> obj_value, uint32_t start, uint32_t end) {
+ Handle<JSTypedArray> array = Handle<JSTypedArray>::cast(receiver);
+ DCHECK(!array->WasNeutered());
+
+ if (!obj_value->IsNumber()) {
+ return FillNumberSlowPath(isolate, array, obj_value, start, end);
+ }
+
+ ctype value = MaybeClamp<ctype>(obj_value, *array);
Camillo Bruni 2017/03/14 09:30:35 I'm not a too big can of the the additional templa
rongjie 2017/03/14 10:08:47 Done. I previously tested similar solution but wi
+
+ // Ensure indexes are within array bounds
+ DCHECK_LE(0, start);
+ DCHECK_LE(start, end);
+ DCHECK_LE(end, array->length_value());
+
+ DisallowHeapAllocation no_gc;
+ BackingStore* elements = BackingStore::cast(receiver->elements());
+ ctype* data = static_cast<ctype*>(elements->DataPtr());
+ std::fill(data + start, data + end, value);
+ return *array;
+ }
+
static Maybe<bool> IncludesValueImpl(Isolate* isolate,
Handle<JSObject> receiver,
Handle<Object> value,
« no previous file with comments | « src/elements.h ('k') | src/js/array.js » ('j') | test/mjsunit/es6/typedarray-fill.js » ('J')

Powered by Google App Engine
This is Rietveld 408576698