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

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

Issue 2497243002: [stubs] Port builtin for Array.push fast-case from Crankshaft to TF (Closed)
Patch Set: Fix GC mole Created 4 years, 1 month 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/code-stubs.h » ('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 6d4ce690ff97f01062099ea524a4ea1c767f1cef..0cad3b77217fe239940179ac5593a3efc2536f68 100644
--- a/src/code-stub-assembler.cc
+++ b/src/code-stub-assembler.cc
@@ -525,6 +525,12 @@ Node* CodeStubAssembler::TaggedIsSmi(Node* a) {
IntPtrConstant(0));
}
+Node* CodeStubAssembler::TaggedIsNotSmi(Node* a) {
+ return WordNotEqual(
+ WordAnd(BitcastTaggedToWord(a), IntPtrConstant(kSmiTagMask)),
+ IntPtrConstant(0));
+}
+
Node* CodeStubAssembler::WordIsPositiveSmi(Node* a) {
return WordEqual(WordAnd(a, IntPtrConstant(kSmiTagMask | kSmiSignMask)),
IntPtrConstant(0));
@@ -653,8 +659,9 @@ void CodeStubAssembler::BranchIfJSObject(Node* object, Label* if_true,
if_true, if_false);
}
-void CodeStubAssembler::BranchIfFastJSArray(Node* object, Node* context,
- Label* if_true, Label* if_false) {
+void CodeStubAssembler::BranchIfFastJSArray(
+ Node* object, Node* context, CodeStubAssembler::FastJSArrayAccessMode mode,
+ Label* if_true, Label* if_false) {
// Bailout if receiver is a Smi.
GotoIf(TaggedIsSmi(object), if_false);
@@ -670,8 +677,9 @@ void CodeStubAssembler::BranchIfFastJSArray(Node* object, Node* context,
GotoUnless(IsFastElementsKind(elements_kind), if_false);
// Check prototype chain if receiver does not have packed elements.
- GotoUnless(IsHoleyFastElementsKind(elements_kind), if_true);
-
+ if (mode == FastJSArrayAccessMode::INBOUNDS_READ) {
+ GotoUnless(IsHoleyFastElementsKind(elements_kind), if_true);
+ }
BranchIfPrototypesHaveNoElements(map, if_true, if_false);
}
@@ -1361,6 +1369,79 @@ Node* CodeStubAssembler::StoreFixedDoubleArrayElement(
return StoreNoWriteBarrier(rep, object, offset, value);
}
+Node* CodeStubAssembler::BuildAppendJSArray(ElementsKind kind, Node* context,
+ Node* array,
+ CodeStubArguments& args,
+ Variable& arg_index,
+ Label* bailout) {
+ Comment("BuildAppendJSArray: %s", ElementsKindToString(kind));
+ Label pre_bailout(this);
+ Label success(this);
+ Variable elements(this, MachineRepresentation::kTagged);
+ ParameterMode mode = OptimalParameterMode();
+ Variable length(this, OptimalParameterRepresentation());
+ length.Bind(UntagParameter(LoadJSArrayLength(array), mode));
+ elements.Bind(LoadElements(array));
+ Node* capacity =
+ UntagParameter(LoadFixedArrayBaseLength(elements.value()), mode);
+
+ // Resize the capacity of the fixed array if it doesn't fit.
+ Label fits(this, &elements);
+ Node* first = arg_index.value();
+ Node* growth = IntPtrSubFoldConstants(args.GetLength(), first);
+ Node* new_length = IntPtrAdd(
+ mode == INTPTR_PARAMETERS ? growth : SmiTag(growth), length.value());
+ GotoUnless(IntPtrGreaterThanOrEqual(new_length, capacity), &fits);
+ Node* new_capacity = CalculateNewElementsCapacity(
+ IntPtrAdd(new_length, IntPtrOrSmiConstant(1, mode)), mode);
+ elements.Bind(GrowElementsCapacity(array, elements.value(), kind, kind,
+ capacity, new_capacity, mode,
+ &pre_bailout));
+ Goto(&fits);
+ Bind(&fits);
+
+ // Push each argument onto the end of the array now that there is enough
+ // capacity.
+ CodeStubAssembler::VariableList push_vars({&length, &elements}, zone());
+ args.ForEach(
+ push_vars,
+ [kind, mode, &length, &elements, &pre_bailout](
+ CodeStubAssembler* assembler, Node* arg) {
+ if (IsFastSmiElementsKind(kind)) {
+ assembler->GotoIf(assembler->TaggedIsNotSmi(arg), &pre_bailout);
+ } else if (IsFastDoubleElementsKind(kind)) {
+ assembler->GotoIfNotNumber(arg, &pre_bailout);
+ }
+ if (IsFastDoubleElementsKind(kind)) {
+ Node* double_value = assembler->ChangeNumberToFloat64(arg);
+ assembler->StoreFixedDoubleArrayElement(
+ elements.value(), length.value(),
+ assembler->Float64SilenceNaN(double_value), mode);
+ } else {
+ WriteBarrierMode barrier_mode = IsFastSmiElementsKind(kind)
+ ? SKIP_WRITE_BARRIER
+ : UPDATE_WRITE_BARRIER;
+ assembler->StoreFixedArrayElement(elements.value(), length.value(),
+ arg, barrier_mode, 0, mode);
+ }
+ assembler->Increment(length, 1, mode);
+ },
+ first, nullptr);
+ length.Bind(TagParameter(length.value(), mode));
+ StoreObjectFieldNoWriteBarrier(array, JSArray::kLengthOffset, length.value());
+ Goto(&success);
+
+ Bind(&pre_bailout);
+ length.Bind(TagParameter(length.value(), mode));
+ Node* diff = SmiSub(length.value(), LoadJSArrayLength(array));
+ StoreObjectFieldNoWriteBarrier(array, JSArray::kLengthOffset, length.value());
+ arg_index.Bind(IntPtrAdd(arg_index.value(), SmiUntag(diff)));
+ Goto(bailout);
+
+ Bind(&success);
+ return length.value();
+}
+
Node* CodeStubAssembler::AllocateHeapNumber(MutableMode mode) {
Node* result = Allocate(HeapNumber::kSize, kNone);
Heap::RootListIndex heap_map_index =
@@ -2130,9 +2211,7 @@ void CodeStubAssembler::CopyStringCharacters(Node* from_string, Node* to_string,
rep, to_string,
index_same ? offset : current_to_offset.value(), value);
if (!index_same) {
- current_to_offset.Bind(assembler->IntPtrAdd(
- current_to_offset.value(),
- assembler->IntPtrConstant(to_increment)));
+ assembler->Increment(current_to_offset, to_increment);
}
},
from_increment, IndexAdvanceMode::kPost);
@@ -2554,6 +2633,25 @@ Node* CodeStubAssembler::ToThisString(Node* context, Node* value,
return var_value.value();
}
+Node* CodeStubAssembler::ChangeNumberToFloat64(compiler::Node* value) {
+ Variable result(this, MachineRepresentation::kFloat64);
+ Label smi(this);
+ Label done(this, &result);
+ GotoIf(TaggedIsSmi(value), &smi);
+ result.Bind(
+ LoadObjectField(value, HeapNumber::kValueOffset, MachineType::Float64()));
+ Goto(&done);
+
+ Bind(&smi);
+ {
+ result.Bind(ChangeInt32ToFloat64(SmiUntag(value)));
+ Goto(&done);
+ }
+
+ Bind(&done);
+ return result.value();
+}
+
Node* CodeStubAssembler::ToThisValue(Node* context, Node* value,
PrimitiveType primitive_type,
char const* method_name) {
@@ -3966,6 +4064,16 @@ void CodeStubAssembler::DecrementCounter(StatsCounter* counter, int delta) {
}
}
+void CodeStubAssembler::Increment(Variable& variable, int value,
+ ParameterMode mode) {
+ DCHECK_IMPLIES(mode == INTPTR_PARAMETERS,
+ variable.rep() == MachineType::PointerRepresentation());
+ DCHECK_IMPLIES(mode == SMI_PARAMETERS,
+ variable.rep() == MachineRepresentation::kTagged ||
+ variable.rep() == MachineRepresentation::kTaggedSigned);
+ variable.Bind(IntPtrAdd(variable.value(), IntPtrOrSmiConstant(value, mode)));
+}
+
void CodeStubAssembler::Use(Label* label) {
GotoIf(Word32Equal(Int32Constant(0), Int32Constant(1)), label);
}
@@ -4126,7 +4234,6 @@ void CodeStubAssembler::NameDictionaryLookup(Node* dictionary,
Goto(&loop);
Bind(&loop);
{
- Node* count = var_count.value();
Node* entry = var_entry.value();
Node* index = EntryToIndex<Dictionary>(entry);
@@ -4143,10 +4250,9 @@ void CodeStubAssembler::NameDictionaryLookup(Node* dictionary,
}
// See Dictionary::NextProbe().
- count = IntPtrAdd(count, IntPtrConstant(1));
- entry = WordAnd(IntPtrAdd(entry, count), mask);
+ Increment(var_count);
+ entry = WordAnd(IntPtrAdd(entry, var_count.value()), mask);
- var_count.Bind(count);
var_entry.Bind(entry);
Goto(&loop);
}
@@ -4209,7 +4315,6 @@ void CodeStubAssembler::NumberDictionaryLookup(Node* dictionary,
Goto(&loop);
Bind(&loop);
{
- Node* count = var_count.value();
Node* entry = var_entry->value();
Node* index = EntryToIndex<Dictionary>(entry);
@@ -4237,10 +4342,9 @@ void CodeStubAssembler::NumberDictionaryLookup(Node* dictionary,
Bind(&next_probe);
// See Dictionary::NextProbe().
- count = IntPtrAdd(count, IntPtrConstant(1));
- entry = WordAnd(IntPtrAdd(entry, count), mask);
+ Increment(var_count);
+ entry = WordAnd(IntPtrAdd(entry, var_count.value()), mask);
- var_count.Bind(count);
var_entry->Bind(entry);
Goto(&loop);
}
@@ -5902,11 +6006,11 @@ void CodeStubAssembler::BuildFastLoop(
Bind(&loop);
{
if (mode == IndexAdvanceMode::kPre) {
- var.Bind(IntPtrAdd(var.value(), IntPtrConstant(increment)));
+ Increment(var, increment);
}
body(this, var.value());
if (mode == IndexAdvanceMode::kPost) {
- var.Bind(IntPtrAdd(var.value(), IntPtrConstant(increment)));
+ Increment(var, increment);
}
Branch(WordNotEqual(var.value(), end_index), &loop, &after_loop);
}
@@ -7545,6 +7649,20 @@ Node* CodeStubAssembler::NumberInc(Node* value) {
return var_result.value();
}
+void CodeStubAssembler::GotoIfNotNumber(Node* input, Label* is_not_number) {
+ Label is_number(this);
+ GotoIf(TaggedIsSmi(input), &is_number);
+ Node* input_map = LoadMap(input);
+ Branch(IsHeapNumberMap(input_map), &is_number, is_not_number);
+ Bind(&is_number);
+}
+
+void CodeStubAssembler::GotoIfNumber(Node* input, Label* is_number) {
+ GotoIf(TaggedIsSmi(input), is_number);
+ Node* input_map = LoadMap(input);
+ GotoIf(IsHeapNumberMap(input_map), is_number);
+}
+
Node* CodeStubAssembler::CreateArrayIterator(Node* array, Node* array_map,
Node* array_type, Node* context,
IterationKind mode) {
@@ -7601,7 +7719,8 @@ Node* CodeStubAssembler::CreateArrayIterator(Node* array, Node* array_map,
Bind(&if_isgeneric);
{
Label if_isfast(this), if_isslow(this);
- BranchIfFastJSArray(array, context, &if_isfast, &if_isslow);
+ BranchIfFastJSArray(array, context, FastJSArrayAccessMode::INBOUNDS_READ,
+ &if_isfast, &if_isslow);
Bind(&if_isfast);
{
@@ -7635,7 +7754,8 @@ Node* CodeStubAssembler::CreateArrayIterator(Node* array, Node* array_map,
Bind(&if_isgeneric);
{
Label if_isfast(this), if_isslow(this);
- BranchIfFastJSArray(array, context, &if_isfast, &if_isslow);
+ BranchIfFastJSArray(array, context, FastJSArrayAccessMode::INBOUNDS_READ,
+ &if_isfast, &if_isslow);
Bind(&if_isfast);
{
@@ -7778,13 +7898,14 @@ CodeStubArguments::CodeStubArguments(CodeStubAssembler* assembler, Node* argc,
}
}
-Node* CodeStubArguments::GetReceiver() {
+Node* CodeStubArguments::GetReceiver() const {
return assembler_->Load(MachineType::AnyTagged(), arguments_,
assembler_->IntPtrConstant(kPointerSize));
}
Node* CodeStubArguments::AtIndex(Node* index,
- CodeStubAssembler::ParameterMode mode) {
+ CodeStubAssembler::ParameterMode mode) const {
+ typedef compiler::Node Node;
Node* negated_index = assembler_->IntPtrSubFoldConstants(
assembler_->IntPtrOrSmiConstant(0, mode), index);
Node* offset =
@@ -7792,7 +7913,7 @@ Node* CodeStubArguments::AtIndex(Node* index,
return assembler_->Load(MachineType::AnyTagged(), arguments_, offset);
}
-Node* CodeStubArguments::AtIndex(int index) {
+Node* CodeStubArguments::AtIndex(int index) const {
return AtIndex(assembler_->IntPtrConstant(index));
}
« no previous file with comments | « src/code-stub-assembler.h ('k') | src/code-stubs.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698