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

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

Issue 2775503006: [builtins] Improve performance of array.prototype.filter and map (Closed)
Patch Set: Code comments Created 3 years, 8 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
« no previous file with comments | « src/code-stub-assembler.h ('k') | src/js/array.js » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/code-stub-assembler.cc
diff --git a/src/code-stub-assembler.cc b/src/code-stub-assembler.cc
index 2a01133efebfa3a32c666a872b0b90a25db3470a..5d4531f6937674a04926f75000ba95da6ce8385c 100644
--- a/src/code-stub-assembler.cc
+++ b/src/code-stub-assembler.cc
@@ -1523,8 +1523,53 @@ 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;
+}
+
+void CodeStubAssembler::PossiblyGrowElementsCapacity(
+ ParameterMode mode, ElementsKind kind, Node* array, Node* length,
+ Variable* var_elements, Node* growth, Label* bailout) {
+ Label fits(this, var_elements);
+ Node* capacity =
+ TaggedToParameter(LoadFixedArrayBaseLength(var_elements->value()), mode);
+ // length and growth nodes are already in a ParameterMode appropriate
+ // representation.
+ Node* new_length = IntPtrOrSmiAdd(growth, length, 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* CodeStubAssembler::BuildAppendJSArray(ElementsKind kind, Node* array,
CodeStubArguments& args,
Variable& arg_index,
Label* bailout) {
@@ -1536,46 +1581,22 @@ Node* CodeStubAssembler::BuildAppendJSArray(ElementsKind kind, Node* context,
VARIABLE(var_length, OptimalParameterRepresentation(),
TaggedToParameter(LoadJSArrayLength(array), mode));
VARIABLE(var_elements, 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* first = arg_index.value();
- Node* growth = IntPtrSub(args.GetLength(), first);
- Node* new_length =
- IntPtrOrSmiAdd(WordToParameter(growth, mode), 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,
- &pre_bailout));
- Goto(&fits);
- BIND(&fits);
- Node* elements = var_elements.value();
+ Node* growth = WordToParameter(IntPtrSub(args.GetLength(), first), mode);
+ PossiblyGrowElementsCapacity(mode, kind, array, var_length.value(),
+ &var_elements, growth, &pre_bailout);
// Push each argument onto the end of the array now that there is enough
// capacity.
CodeStubAssembler::VariableList push_vars({&var_length}, zone());
+ Node* elements = var_elements.value();
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);
@@ -1600,6 +1621,49 @@ 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);
+ }
+}
+
+void CodeStubAssembler::BuildAppendJSArray(ElementsKind kind, Node* array,
+ Node* value, Label* bailout) {
+ Comment("BuildAppendJSArray: %s", ElementsKindToString(kind));
+ ParameterMode mode = OptimalParameterMode();
+ VARIABLE(var_length, OptimalParameterRepresentation(),
+ TaggedToParameter(LoadJSArrayLength(array), mode));
+ VARIABLE(var_elements, MachineRepresentation::kTagged, LoadElements(array));
+
+ // Resize the capacity of the fixed array if it doesn't fit.
+ Node* growth = IntPtrOrSmiConstant(1, mode);
+ PossiblyGrowElementsCapacity(mode, kind, array, var_length.value(),
+ &var_elements, growth, bailout);
+
+ // Push each argument onto the end of the array now that there is enough
+ // capacity.
+ TryStoreArrayElement(kind, mode, bailout, var_elements.value(),
+ var_length.value(), value);
+ Increment(var_length, 1, mode);
+
+ Node* length = ParameterToTagged(var_length.value(), mode);
+ StoreObjectFieldNoWriteBarrier(array, JSArray::kLengthOffset, length);
+}
+
Node* CodeStubAssembler::AllocateHeapNumber(MutableMode mode) {
Node* result = Allocate(HeapNumber::kSize, kNone);
Heap::RootListIndex heap_map_index =
@@ -8485,6 +8549,11 @@ Node* CodeStubAssembler::IsHoleyFastElementsKind(Node* elements_kind) {
return Word32Equal(holey_elements, Int32Constant(1));
}
+Node* CodeStubAssembler::IsElementsKindGreaterThan(
+ Node* target_kind, ElementsKind reference_kind) {
+ return Int32GreaterThan(target_kind, Int32Constant(reference_kind));
+}
+
Node* CodeStubAssembler::IsDebugActive() {
Node* is_debug_active = Load(
MachineType::Uint8(),
« no previous file with comments | « src/code-stub-assembler.h ('k') | src/js/array.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698