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

Unified Diff: src/code-stub-assembler.cc

Issue 2775503006: [builtins] Improve performance of array.prototype.filter and map (Closed)
Patch Set: Remove old impl. 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/code-stub-assembler.cc
diff --git a/src/code-stub-assembler.cc b/src/code-stub-assembler.cc
index 85db0fbc6ec6219ddeb470d37b8b0ff909f9ea0f..1ff5a1824d140392aee567cbf116ace0a18b3a70 100644
--- a/src/code-stub-assembler.cc
+++ b/src/code-stub-assembler.cc
@@ -1459,8 +1459,35 @@ Node* CodeStubAssembler::StoreFixedDoubleArrayElement(
return StoreNoWriteBarrier(rep, object, offset, value);
}
-Node* CodeStubAssembler::BuildAppendJSArray(ElementsKind kind, Node* context,
- Node* array,
+Node* CodeStubAssembler::EnsureArrayPushable(Node* receiver, Label* bailout) {
+ // Disallow pushing onto prototypes. It might be the JSArray prototype.
+ // Disallow pushing onto non-extensible objects.
+ Comment("Disallow pushing onto prototypes");
+ Node* map = LoadMap(receiver);
+ Node* bit_field2 = LoadMapBitField2(map);
+ int mask = static_cast<int>(Map::IsPrototypeMapBits::kMask) |
+ (1 << Map::kIsExtensible);
+ Node* test = Word32And(bit_field2, Int32Constant(mask));
+ GotoIf(Word32NotEqual(test, Int32Constant(1 << Map::kIsExtensible)), bailout);
+
+ // Disallow pushing onto arrays in dictionary named property mode. We need
+ // to figure out whether the length property is still writable.
+ Comment("Disallow pushing onto arrays in dictionary named property mode");
+ GotoIf(IsDictionaryMap(map), bailout);
+
+ // Check whether the length property is writable. The length property is the
+ // only default named property on arrays. It's nonconfigurable, hence is
+ // guaranteed to stay the first property.
+ Node* descriptors = LoadMapDescriptors(map);
+ Node* details =
+ LoadFixedArrayElement(descriptors, DescriptorArray::ToDetailsIndex(0));
+ GotoIf(IsSetSmi(details, PropertyDetails::kAttributesReadOnlyMask), bailout);
+
+ Node* kind = DecodeWord32<Map::ElementsKindBits>(bit_field2);
+ return kind;
+}
+
+Node* CodeStubAssembler::BuildAppendJSArray(ElementsKind kind, Node* array,
CodeStubArguments& args,
Variable& arg_index,
Label* bailout) {
@@ -1497,22 +1524,8 @@ Node* CodeStubAssembler::BuildAppendJSArray(ElementsKind kind, Node* context,
args.ForEach(
push_vars,
[this, kind, mode, elements, &var_length, &pre_bailout](Node* arg) {
- if (IsFastSmiElementsKind(kind)) {
- GotoIf(TaggedIsNotSmi(arg), &pre_bailout);
- } else if (IsFastDoubleElementsKind(kind)) {
- GotoIfNotNumber(arg, &pre_bailout);
- }
- if (IsFastDoubleElementsKind(kind)) {
- Node* double_value = ChangeNumberToFloat64(arg);
- StoreFixedDoubleArrayElement(elements, var_length.value(),
- Float64SilenceNaN(double_value), mode);
- } else {
- WriteBarrierMode barrier_mode = IsFastSmiElementsKind(kind)
- ? SKIP_WRITE_BARRIER
- : UPDATE_WRITE_BARRIER;
- StoreFixedArrayElement(elements, var_length.value(), arg,
- barrier_mode, 0, mode);
- }
+ TryStoreArrayElement(kind, mode, &pre_bailout, elements,
+ var_length.value(), arg);
Increment(var_length, 1, mode);
},
first, nullptr);
@@ -1537,6 +1550,69 @@ Node* CodeStubAssembler::BuildAppendJSArray(ElementsKind kind, Node* context,
return var_tagged_length.value();
}
+void CodeStubAssembler::TryStoreArrayElement(ElementsKind kind,
+ ParameterMode mode, Label* bailout,
+ Node* elements, Node* index,
+ Node* value) {
+ if (IsFastSmiElementsKind(kind)) {
+ GotoIf(TaggedIsNotSmi(value), bailout);
+ } else if (IsFastDoubleElementsKind(kind)) {
+ GotoIfNotNumber(value, bailout);
+ }
+ if (IsFastDoubleElementsKind(kind)) {
+ Node* double_value = ChangeNumberToFloat64(value);
+ StoreFixedDoubleArrayElement(elements, index,
+ Float64SilenceNaN(double_value), mode);
+ } else {
+ WriteBarrierMode barrier_mode =
+ IsFastSmiElementsKind(kind) ? SKIP_WRITE_BARRIER : UPDATE_WRITE_BARRIER;
+ StoreFixedArrayElement(elements, index, value, barrier_mode, 0, mode);
+ }
+}
+
+Node* CodeStubAssembler::BuildAppendJSArray(ElementsKind kind, Node* array,
+ Node* value, Label* bailout) {
+ Comment("BuildAppendJSArray: %s", ElementsKindToString(kind));
+ Label success(this);
+ Variable var_tagged_length(this, MachineRepresentation::kTagged);
+ ParameterMode mode = OptimalParameterMode();
+ Variable var_length(this, OptimalParameterRepresentation(),
+ TaggedToParameter(LoadJSArrayLength(array), mode));
+ Variable var_elements(this, MachineRepresentation::kTagged,
+ LoadElements(array));
+ Node* capacity =
+ TaggedToParameter(LoadFixedArrayBaseLength(var_elements.value()), mode);
+
+ // Resize the capacity of the fixed array if it doesn't fit.
+ Label fits(this, &var_elements);
+ Node* growth = IntPtrOrSmiConstant(1, mode);
danno 2017/04/03 15:35:27 This prologue and grow code looks quite similar be
mvstanton 2017/04/06 08:57:36 Done.
+ Node* new_length = IntPtrOrSmiAdd(growth, var_length.value(), mode);
+ GotoIfNot(IntPtrOrSmiGreaterThan(new_length, capacity, mode), &fits);
+ Node* new_capacity = CalculateNewElementsCapacity(new_length, mode);
+ var_elements.Bind(GrowElementsCapacity(array, var_elements.value(), kind,
+ kind, capacity, new_capacity, mode,
+ bailout));
+ Goto(&fits);
+ Bind(&fits);
+ Node* elements = var_elements.value();
+
+ // Push each argument onto the end of the array now that there is enough
+ // capacity.
+ TryStoreArrayElement(kind, mode, bailout, elements, var_length.value(),
+ value);
+ Increment(var_length, 1, mode);
+
+ {
+ Node* length = ParameterToTagged(var_length.value(), mode);
+ var_tagged_length.Bind(length);
+ StoreObjectFieldNoWriteBarrier(array, JSArray::kLengthOffset, length);
+ Goto(&success);
+ }
+
+ Bind(&success);
+ return var_tagged_length.value();
+}
+
Node* CodeStubAssembler::AllocateHeapNumber(MutableMode mode) {
Node* result = Allocate(HeapNumber::kSize, kNone);
Heap::RootListIndex heap_map_index =

Powered by Google App Engine
This is Rietveld 408576698