summaryrefslogtreecommitdiff
path: root/deps/v8/src/code-stub-assembler.cc
diff options
context:
space:
mode:
Diffstat (limited to 'deps/v8/src/code-stub-assembler.cc')
-rw-r--r--deps/v8/src/code-stub-assembler.cc1250
1 files changed, 605 insertions, 645 deletions
diff --git a/deps/v8/src/code-stub-assembler.cc b/deps/v8/src/code-stub-assembler.cc
index e36a5cc796..f98e7fe519 100644
--- a/deps/v8/src/code-stub-assembler.cc
+++ b/deps/v8/src/code-stub-assembler.cc
@@ -175,7 +175,9 @@ Node* CodeStubAssembler::SelectSmiConstant(Node* condition, Smi* true_value,
MachineRepresentation::kTaggedSigned);
}
-Node* CodeStubAssembler::NoContextConstant() { return SmiConstant(0); }
+Node* CodeStubAssembler::NoContextConstant() {
+ return SmiConstant(Context::kNoContext);
+}
#define HEAP_CONSTANT_ACCESSOR(rootIndexName, rootAccessorName, name) \
compiler::TNode<std::remove_reference<decltype( \
@@ -546,8 +548,8 @@ TNode<Object> CodeStubAssembler::NumberMax(SloppyTNode<Object> a,
// TODO(danno): This could be optimized by specifically handling smi cases.
VARIABLE(result, MachineRepresentation::kTagged);
Label done(this), greater_than_equal_a(this), greater_than_equal_b(this);
- GotoIfNumericGreaterThanOrEqual(a, b, &greater_than_equal_a);
- GotoIfNumericGreaterThanOrEqual(b, a, &greater_than_equal_b);
+ GotoIfNumberGreaterThanOrEqual(a, b, &greater_than_equal_a);
+ GotoIfNumberGreaterThanOrEqual(b, a, &greater_than_equal_b);
result.Bind(NanConstant());
Goto(&done);
BIND(&greater_than_equal_a);
@@ -565,8 +567,8 @@ TNode<Object> CodeStubAssembler::NumberMin(SloppyTNode<Object> a,
// TODO(danno): This could be optimized by specifically handling smi cases.
VARIABLE(result, MachineRepresentation::kTagged);
Label done(this), greater_than_equal_a(this), greater_than_equal_b(this);
- GotoIfNumericGreaterThanOrEqual(a, b, &greater_than_equal_a);
- GotoIfNumericGreaterThanOrEqual(b, a, &greater_than_equal_b);
+ GotoIfNumberGreaterThanOrEqual(a, b, &greater_than_equal_a);
+ GotoIfNumberGreaterThanOrEqual(b, a, &greater_than_equal_b);
result.Bind(NanConstant());
Goto(&done);
BIND(&greater_than_equal_a);
@@ -642,8 +644,9 @@ Node* CodeStubAssembler::SmiMod(Node* a, Node* b) {
return TNode<Object>::UncheckedCast(var_result.value());
}
-Node* CodeStubAssembler::SmiMul(Node* a, Node* b) {
- VARIABLE(var_result, MachineRepresentation::kTagged);
+TNode<Number> CodeStubAssembler::SmiMul(SloppyTNode<Smi> a,
+ SloppyTNode<Smi> b) {
+ TVARIABLE(Number, var_result);
VARIABLE(var_lhs_float64, MachineRepresentation::kFloat64);
VARIABLE(var_rhs_float64, MachineRepresentation::kFloat64);
Label return_result(this, &var_result);
@@ -668,7 +671,7 @@ Node* CodeStubAssembler::SmiMul(Node* a, Node* b) {
Branch(Word32Equal(answer, zero), &answer_zero, &answer_not_zero);
BIND(&answer_not_zero);
{
- var_result.Bind(ChangeInt32ToTagged(answer));
+ var_result = ChangeInt32ToTagged(answer);
Goto(&return_result);
}
BIND(&answer_zero);
@@ -679,12 +682,12 @@ Node* CodeStubAssembler::SmiMul(Node* a, Node* b) {
&if_should_be_zero);
BIND(&if_should_be_negative_zero);
{
- var_result.Bind(MinusZeroConstant());
+ var_result = MinusZeroConstant();
Goto(&return_result);
}
BIND(&if_should_be_zero);
{
- var_result.Bind(SmiConstant(0));
+ var_result = SmiConstant(0);
Goto(&return_result);
}
}
@@ -694,13 +697,12 @@ Node* CodeStubAssembler::SmiMul(Node* a, Node* b) {
var_lhs_float64.Bind(SmiToFloat64(a));
var_rhs_float64.Bind(SmiToFloat64(b));
Node* value = Float64Mul(var_lhs_float64.value(), var_rhs_float64.value());
- Node* result = AllocateHeapNumberWithValue(value);
- var_result.Bind(result);
+ var_result = AllocateHeapNumberWithValue(value);
Goto(&return_result);
}
BIND(&return_result);
- return var_result.value();
+ return var_result;
}
Node* CodeStubAssembler::TrySmiDiv(Node* dividend, Node* divisor,
@@ -898,7 +900,7 @@ void CodeStubAssembler::BranchIfFastJSArrayForCopy(Node* object, Node* context,
}
void CodeStubAssembler::GotoIfForceSlowPath(Label* if_true) {
-#if defined(DEBUG) || defined(ENABLE_FASTSLOW_SWITCH)
+#ifdef V8_ENABLE_FORCE_SLOW_PATH
Node* const force_slow_path_addr =
ExternalConstant(ExternalReference::force_slow_path(isolate()));
Node* const force_slow = Load(MachineType::Uint8(), force_slow_path_addr);
@@ -1534,14 +1536,15 @@ Node* CodeStubAssembler::LoadJSValueValue(Node* object) {
return LoadObjectField(object, JSValue::kValueOffset);
}
-Node* CodeStubAssembler::LoadWeakCellValueUnchecked(Node* weak_cell) {
+TNode<Object> CodeStubAssembler::LoadWeakCellValueUnchecked(Node* weak_cell) {
// TODO(ishell): fix callers.
return LoadObjectField(weak_cell, WeakCell::kValueOffset);
}
-Node* CodeStubAssembler::LoadWeakCellValue(Node* weak_cell, Label* if_cleared) {
+TNode<Object> CodeStubAssembler::LoadWeakCellValue(
+ SloppyTNode<WeakCell> weak_cell, Label* if_cleared) {
CSA_ASSERT(this, IsWeakCell(weak_cell));
- Node* value = LoadWeakCellValueUnchecked(weak_cell);
+ TNode<Object> value = LoadWeakCellValueUnchecked(weak_cell);
if (if_cleared != nullptr) {
GotoIf(WordEqual(value, IntPtrConstant(0)), if_cleared);
}
@@ -1624,17 +1627,16 @@ Node* CodeStubAssembler::LoadFixedTypedArrayElementAsTagged(
}
}
-Node* CodeStubAssembler::LoadFeedbackVectorSlot(Node* object,
- Node* slot_index_node,
- int additional_offset,
- ParameterMode parameter_mode) {
+TNode<Object> CodeStubAssembler::LoadFeedbackVectorSlot(
+ Node* object, Node* slot_index_node, int additional_offset,
+ ParameterMode parameter_mode) {
CSA_SLOW_ASSERT(this, IsFeedbackVector(object));
CSA_SLOW_ASSERT(this, MatchesParameterMode(slot_index_node, parameter_mode));
int32_t header_size =
FeedbackVector::kFeedbackSlotsOffset + additional_offset - kHeapObjectTag;
Node* offset = ElementOffsetFromIndex(slot_index_node, HOLEY_ELEMENTS,
parameter_mode, header_size);
- return Load(MachineType::AnyTagged(), object, offset);
+ return UncheckedCast<Object>(Load(MachineType::AnyTagged(), object, offset));
}
Node* CodeStubAssembler::LoadAndUntagToWord32FixedArrayElement(
@@ -1788,8 +1790,8 @@ Node* CodeStubAssembler::LoadJSFunctionPrototype(Node* function,
CSA_ASSERT(this, TaggedIsNotSmi(function));
CSA_ASSERT(this, IsJSFunction(function));
CSA_ASSERT(this, IsFunctionWithPrototypeSlotMap(LoadMap(function)));
- CSA_ASSERT(this, IsClearWord32(LoadMapBitField(LoadMap(function)),
- 1 << Map::kHasNonInstancePrototype));
+ CSA_ASSERT(this, IsClearWord32<Map::HasNonInstancePrototypeBit>(
+ LoadMapBitField(LoadMap(function))));
Node* proto_or_map =
LoadObjectField(function, JSFunction::kPrototypeOrInitialMapOffset);
GotoIf(IsTheHole(proto_or_map), if_bailout);
@@ -1943,10 +1945,10 @@ Node* CodeStubAssembler::EnsureArrayPushable(Node* receiver, Label* bailout) {
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);
+ int mask = Map::IsPrototypeMapBit::kMask | Map::IsExtensibleBit::kMask;
Node* test = Word32And(bit_field2, Int32Constant(mask));
- GotoIf(Word32NotEqual(test, Int32Constant(1 << Map::kIsExtensible)), bailout);
+ GotoIf(Word32NotEqual(test, Int32Constant(Map::IsExtensibleBit::kMask)),
+ bailout);
// Disallow pushing onto arrays in dictionary named property mode. We need
// to figure out whether the length property is still writable.
@@ -1994,7 +1996,10 @@ TNode<Smi> CodeStubAssembler::BuildAppendJSArray(ElementsKind kind,
// Resize the capacity of the fixed array if it doesn't fit.
TNode<IntPtrT> first = *arg_index;
- Node* growth = WordToParameter(IntPtrSub(args->GetLength(), first), mode);
+ Node* growth = WordToParameter(
+ IntPtrSub(UncheckedCast<IntPtrT>(args->GetLength(INTPTR_PARAMETERS)),
+ first),
+ mode);
PossiblyGrowElementsCapacity(mode, kind, array, var_length.value(),
&var_elements, growth, &pre_bailout);
@@ -2548,8 +2553,8 @@ void CodeStubAssembler::InitializeJSObjectFromMap(
void CodeStubAssembler::InitializeJSObjectBodyNoSlackTracking(
Node* object, Node* map, Node* instance_size, int start_offset) {
STATIC_ASSERT(Map::kNoSlackTracking == 0);
- CSA_ASSERT(this,
- IsClearWord32<Map::ConstructionCounter>(LoadMapBitField3(map)));
+ CSA_ASSERT(
+ this, IsClearWord32<Map::ConstructionCounterBits>(LoadMapBitField3(map)));
InitializeFieldsWithRoot(object, IntPtrConstant(start_offset), instance_size,
Heap::kUndefinedValueRootIndex);
}
@@ -2564,7 +2569,8 @@ void CodeStubAssembler::InitializeJSObjectBodyWithSlackTracking(
Node* bit_field3 = LoadMapBitField3(map);
Label end(this), slack_tracking(this), complete(this, Label::kDeferred);
STATIC_ASSERT(Map::kNoSlackTracking == 0);
- GotoIf(IsSetWord32<Map::ConstructionCounter>(bit_field3), &slack_tracking);
+ GotoIf(IsSetWord32<Map::ConstructionCounterBits>(bit_field3),
+ &slack_tracking);
Comment("No slack tracking");
InitializeJSObjectBodyNoSlackTracking(object, map, instance_size);
Goto(&end);
@@ -2574,9 +2580,9 @@ void CodeStubAssembler::InitializeJSObjectBodyWithSlackTracking(
Comment("Decrease construction counter");
// Slack tracking is only done on initial maps.
CSA_ASSERT(this, IsUndefined(LoadMapBackPointer(map)));
- STATIC_ASSERT(Map::ConstructionCounter::kNext == 32);
+ STATIC_ASSERT(Map::ConstructionCounterBits::kNext == 32);
Node* new_bit_field3 = Int32Sub(
- bit_field3, Int32Constant(1 << Map::ConstructionCounter::kShift));
+ bit_field3, Int32Constant(1 << Map::ConstructionCounterBits::kShift));
StoreObjectFieldNoWriteBarrier(map, Map::kBitField3Offset, new_bit_field3,
MachineRepresentation::kWord32);
STATIC_ASSERT(Map::kSlackTrackingCounterEnd == 1);
@@ -2595,7 +2601,9 @@ void CodeStubAssembler::InitializeJSObjectBodyWithSlackTracking(
InitializeFieldsWithRoot(object, IntPtrConstant(start_offset), used_size,
Heap::kUndefinedValueRootIndex);
- GotoIf(IsClearWord32<Map::ConstructionCounter>(new_bit_field3), &complete);
+ STATIC_ASSERT(Map::kNoSlackTracking == 0);
+ GotoIf(IsClearWord32<Map::ConstructionCounterBits>(new_bit_field3),
+ &complete);
Goto(&end);
}
@@ -3346,7 +3354,8 @@ Node* CodeStubAssembler::CalculateNewElementsCapacity(Node* old_capacity,
CSA_SLOW_ASSERT(this, MatchesParameterMode(old_capacity, mode));
Node* half_old_capacity = WordOrSmiShr(old_capacity, 1, mode);
Node* new_capacity = IntPtrOrSmiAdd(half_old_capacity, old_capacity, mode);
- Node* padding = IntPtrOrSmiConstant(16, mode);
+ Node* padding =
+ IntPtrOrSmiConstant(JSObject::kMinAddedElementsCapacity, mode);
return IntPtrOrSmiAdd(new_capacity, padding, mode);
}
@@ -3505,8 +3514,8 @@ Node* CodeStubAssembler::TruncateTaggedToFloat64(Node* context, Node* value) {
Node* CodeStubAssembler::TruncateTaggedToWord32(Node* context, Node* value) {
VARIABLE(var_result, MachineRepresentation::kWord32);
Label done(this);
- TaggedToWord32OrBigIntImpl<Feedback::kNone, Object::Conversion::kToNumber>(
- context, value, &done, &var_result);
+ TaggedToWord32OrBigIntImpl<Object::Conversion::kToNumber>(context, value,
+ &done, &var_result);
BIND(&done);
return var_result.value();
}
@@ -3518,7 +3527,7 @@ void CodeStubAssembler::TaggedToWord32OrBigInt(Node* context, Node* value,
Variable* var_word32,
Label* if_bigint,
Variable* var_bigint) {
- TaggedToWord32OrBigIntImpl<Feedback::kNone, Object::Conversion::kToNumeric>(
+ TaggedToWord32OrBigIntImpl<Object::Conversion::kToNumeric>(
context, value, if_number, var_word32, if_bigint, var_bigint);
}
@@ -3528,13 +3537,12 @@ void CodeStubAssembler::TaggedToWord32OrBigInt(Node* context, Node* value,
void CodeStubAssembler::TaggedToWord32OrBigIntWithFeedback(
Node* context, Node* value, Label* if_number, Variable* var_word32,
Label* if_bigint, Variable* var_bigint, Variable* var_feedback) {
- TaggedToWord32OrBigIntImpl<Feedback::kCollect,
- Object::Conversion::kToNumeric>(
+ TaggedToWord32OrBigIntImpl<Object::Conversion::kToNumeric>(
context, value, if_number, var_word32, if_bigint, var_bigint,
var_feedback);
}
-template <CodeStubAssembler::Feedback feedback, Object::Conversion conversion>
+template <Object::Conversion conversion>
void CodeStubAssembler::TaggedToWord32OrBigIntImpl(
Node* context, Node* value, Label* if_number, Variable* var_word32,
Label* if_bigint, Variable* var_bigint, Variable* var_feedback) {
@@ -3546,14 +3554,10 @@ void CodeStubAssembler::TaggedToWord32OrBigIntImpl(
// We might need to loop after conversion.
VARIABLE(var_value, MachineRepresentation::kTagged, value);
- if (feedback == Feedback::kCollect) {
- var_feedback->Bind(SmiConstant(BinaryOperationFeedback::kNone));
- } else {
- DCHECK(var_feedback == nullptr);
- }
+ OverwriteFeedback(var_feedback, BinaryOperationFeedback::kNone);
Variable* loop_vars[] = {&var_value, var_feedback};
- int num_vars = feedback == Feedback::kCollect ? arraysize(loop_vars)
- : arraysize(loop_vars) - 1;
+ int num_vars =
+ var_feedback != nullptr ? arraysize(loop_vars) : arraysize(loop_vars) - 1;
Label loop(this, num_vars, loop_vars);
Goto(&loop);
BIND(&loop);
@@ -3565,11 +3569,7 @@ void CodeStubAssembler::TaggedToWord32OrBigIntImpl(
// {value} is a Smi.
var_word32->Bind(SmiToWord32(value));
- if (feedback == Feedback::kCollect) {
- var_feedback->Bind(
- SmiOr(var_feedback->value(),
- SmiConstant(BinaryOperationFeedback::kSignedSmall)));
- }
+ CombineFeedback(var_feedback, BinaryOperationFeedback::kSignedSmall);
Goto(if_number);
BIND(&not_smi);
@@ -3582,7 +3582,7 @@ void CodeStubAssembler::TaggedToWord32OrBigIntImpl(
// Not HeapNumber (or BigInt if conversion == kToNumeric).
{
- if (feedback == Feedback::kCollect) {
+ if (var_feedback != nullptr) {
// We do not require an Or with earlier feedback here because once we
// convert the value to a Numeric, we cannot reach this path. We can
// only reach this path on the first pass when the feedback is kNone.
@@ -3595,36 +3595,25 @@ void CodeStubAssembler::TaggedToWord32OrBigIntImpl(
? Builtins::kNonNumberToNumeric
: Builtins::kNonNumberToNumber;
var_value.Bind(CallBuiltin(builtin, context, value));
- if (feedback == Feedback::kCollect) {
- var_feedback->Bind(SmiConstant(BinaryOperationFeedback::kAny));
- }
+ OverwriteFeedback(var_feedback, BinaryOperationFeedback::kAny);
Goto(&loop);
BIND(&is_oddball);
var_value.Bind(LoadObjectField(value, Oddball::kToNumberOffset));
- if (feedback == Feedback::kCollect) {
- var_feedback->Bind(
- SmiConstant(BinaryOperationFeedback::kNumberOrOddball));
- }
+ OverwriteFeedback(var_feedback,
+ BinaryOperationFeedback::kNumberOrOddball);
Goto(&loop);
}
BIND(&is_heap_number);
var_word32->Bind(TruncateHeapNumberValueToWord32(value));
- if (feedback == Feedback::kCollect) {
- var_feedback->Bind(SmiOr(var_feedback->value(),
- SmiConstant(BinaryOperationFeedback::kNumber)));
- }
+ CombineFeedback(var_feedback, BinaryOperationFeedback::kNumber);
Goto(if_number);
if (conversion == Object::Conversion::kToNumeric) {
BIND(&is_bigint);
var_bigint->Bind(value);
- if (feedback == Feedback::kCollect) {
- var_feedback->Bind(
- SmiOr(var_feedback->value(),
- SmiConstant(BinaryOperationFeedback::kBigInt)));
- }
+ CombineFeedback(var_feedback, BinaryOperationFeedback::kBigInt);
Goto(if_bigint);
}
}
@@ -3822,9 +3811,7 @@ TNode<Float64T> CodeStubAssembler::ChangeNumberToFloat64(
}
TNode<UintPtrT> CodeStubAssembler::ChangeNonnegativeNumberToUintPtr(
- SloppyTNode<Number> value) {
- // TODO(tebbi): Remove assert once argument is TNode instead of SloppyTNode.
- CSA_SLOW_ASSERT(this, IsNumber(value));
+ TNode<Number> value) {
TVARIABLE(UintPtrT, result);
Label smi(this), done(this, &result);
GotoIf(TaggedIsSmi(value), &smi);
@@ -4032,43 +4019,30 @@ Node* CodeStubAssembler::InstanceTypeEqual(Node* instance_type, int type) {
return Word32Equal(instance_type, Int32Constant(type));
}
-Node* CodeStubAssembler::IsSpecialReceiverMap(Node* map) {
- CSA_SLOW_ASSERT(this, IsMap(map));
- Node* is_special = IsSpecialReceiverInstanceType(LoadMapInstanceType(map));
- uint32_t mask =
- 1 << Map::kHasNamedInterceptor | 1 << Map::kIsAccessCheckNeeded;
- USE(mask);
- // Interceptors or access checks imply special receiver.
- CSA_ASSERT(this,
- SelectConstant(IsSetWord32(LoadMapBitField(map), mask), is_special,
- Int32Constant(1), MachineRepresentation::kWord32));
- return is_special;
-}
-
TNode<BoolT> CodeStubAssembler::IsDictionaryMap(SloppyTNode<Map> map) {
CSA_SLOW_ASSERT(this, IsMap(map));
Node* bit_field3 = LoadMapBitField3(map);
- return IsSetWord32<Map::DictionaryMap>(bit_field3);
+ return IsSetWord32<Map::IsDictionaryMapBit>(bit_field3);
}
Node* CodeStubAssembler::IsExtensibleMap(Node* map) {
CSA_ASSERT(this, IsMap(map));
- return IsSetWord32(LoadMapBitField2(map), 1 << Map::kIsExtensible);
+ return IsSetWord32<Map::IsExtensibleBit>(LoadMapBitField2(map));
}
Node* CodeStubAssembler::IsCallableMap(Node* map) {
CSA_ASSERT(this, IsMap(map));
- return IsSetWord32(LoadMapBitField(map), 1 << Map::kIsCallable);
+ return IsSetWord32<Map::IsCallableBit>(LoadMapBitField(map));
}
Node* CodeStubAssembler::IsDeprecatedMap(Node* map) {
CSA_ASSERT(this, IsMap(map));
- return IsSetWord32<Map::Deprecated>(LoadMapBitField3(map));
+ return IsSetWord32<Map::IsDeprecatedBit>(LoadMapBitField3(map));
}
Node* CodeStubAssembler::IsUndetectableMap(Node* map) {
CSA_ASSERT(this, IsMap(map));
- return IsSetWord32(LoadMapBitField(map), 1 << Map::kIsUndetectable);
+ return IsSetWord32<Map::IsUndetectableBit>(LoadMapBitField(map));
}
Node* CodeStubAssembler::IsNoElementsProtectorCellInvalid() {
@@ -4104,7 +4078,7 @@ Node* CodeStubAssembler::IsCell(Node* object) {
Node* CodeStubAssembler::IsConstructorMap(Node* map) {
CSA_ASSERT(this, IsMap(map));
- return IsSetWord32(LoadMapBitField(map), 1 << Map::kIsConstructor);
+ return IsSetWord32<Map::IsConstructorBit>(LoadMapBitField(map));
}
Node* CodeStubAssembler::IsConstructor(Node* object) {
@@ -4113,7 +4087,7 @@ Node* CodeStubAssembler::IsConstructor(Node* object) {
Node* CodeStubAssembler::IsFunctionWithPrototypeSlotMap(Node* map) {
CSA_ASSERT(this, IsMap(map));
- return IsSetWord32(LoadMapBitField(map), 1 << Map::kHasPrototypeSlot);
+ return IsSetWord32<Map::HasPrototypeSlotBit>(LoadMapBitField(map));
}
Node* CodeStubAssembler::IsSpecialReceiverInstanceType(Node* instance_type) {
@@ -4500,13 +4474,12 @@ Node* CodeStubAssembler::IsNumberArrayIndex(Node* number) {
Label check_upper_bound(this), check_is_integer(this), out(this),
return_false(this);
- GotoIfNumericGreaterThanOrEqual(number, NumberConstant(0),
- &check_upper_bound);
+ GotoIfNumberGreaterThanOrEqual(number, NumberConstant(0), &check_upper_bound);
Goto(&return_false);
BIND(&check_upper_bound);
- GotoIfNumericGreaterThanOrEqual(number, NumberConstant(kMaxUInt32),
- &return_false);
+ GotoIfNumberGreaterThanOrEqual(number, NumberConstant(kMaxUInt32),
+ &return_false);
Goto(&check_is_integer);
BIND(&check_is_integer);
@@ -4525,14 +4498,14 @@ Node* CodeStubAssembler::IsNumberArrayIndex(Node* number) {
return var_result.value();
}
-TNode<Uint32T> CodeStubAssembler::StringCharCodeAt(SloppyTNode<String> string,
- SloppyTNode<IntPtrT> index) {
+TNode<Int32T> CodeStubAssembler::StringCharCodeAt(SloppyTNode<String> string,
+ SloppyTNode<IntPtrT> index) {
CSA_ASSERT(this, IsString(string));
CSA_ASSERT(this, IntPtrGreaterThanOrEqual(index, IntPtrConstant(0)));
CSA_ASSERT(this, IntPtrLessThan(index, LoadStringLengthAsWord(string)));
- VARIABLE(var_result, MachineRepresentation::kWord32);
+ TVARIABLE(Int32T, var_result);
Label return_result(this), if_runtime(this, Label::kDeferred),
if_stringistwobyte(this), if_stringisonebyte(this);
@@ -4550,14 +4523,16 @@ TNode<Uint32T> CodeStubAssembler::StringCharCodeAt(SloppyTNode<String> string,
BIND(&if_stringisonebyte);
{
- var_result.Bind(Load(MachineType::Uint8(), string_data, offset));
+ var_result =
+ UncheckedCast<Int32T>(Load(MachineType::Uint8(), string_data, offset));
Goto(&return_result);
}
BIND(&if_stringistwobyte);
{
- var_result.Bind(Load(MachineType::Uint16(), string_data,
- WordShl(offset, IntPtrConstant(1))));
+ var_result =
+ UncheckedCast<Int32T>(Load(MachineType::Uint16(), string_data,
+ WordShl(offset, IntPtrConstant(1))));
Goto(&return_result);
}
@@ -4565,15 +4540,15 @@ TNode<Uint32T> CodeStubAssembler::StringCharCodeAt(SloppyTNode<String> string,
{
Node* result = CallRuntime(Runtime::kStringCharCodeAt, NoContextConstant(),
string, SmiTag(index));
- var_result.Bind(SmiToWord32(result));
+ var_result = SmiToWord32(result);
Goto(&return_result);
}
BIND(&return_result);
- return UncheckedCast<Uint32T>(var_result.value());
+ return var_result;
}
-Node* CodeStubAssembler::StringFromCharCode(Node* code) {
+TNode<String> CodeStubAssembler::StringFromCharCode(TNode<Int32T> code) {
VARIABLE(var_result, MachineRepresentation::kTagged);
// Check if the {code} is a one-byte char code.
@@ -4627,7 +4602,7 @@ Node* CodeStubAssembler::StringFromCharCode(Node* code) {
BIND(&if_done);
CSA_ASSERT(this, IsString(var_result.value()));
- return var_result.value();
+ return CAST(var_result.value());
}
// A wrapper around CopyStringCharacters which determines the correct string
@@ -4787,7 +4762,7 @@ Node* CodeStubAssembler::SubString(Node* context, Node* string, Node* from,
// Substrings of length 1 are generated through CharCodeAt and FromCharCode.
BIND(&single_char);
{
- Node* char_code = StringCharCodeAt(string, SmiUntag(from));
+ TNode<Int32T> char_code = StringCharCodeAt(string, SmiUntag(from));
var_result.Bind(StringFromCharCode(char_code));
Goto(&end);
}
@@ -5161,8 +5136,8 @@ Node* CodeStubAssembler::StringAdd(Node* context, Node* left, Node* right,
return result.value();
}
-Node* CodeStubAssembler::StringFromCodePoint(Node* codepoint,
- UnicodeEncoding encoding) {
+TNode<String> CodeStubAssembler::StringFromCodePoint(TNode<Int32T> codepoint,
+ UnicodeEncoding encoding) {
VARIABLE(var_result, MachineRepresentation::kTagged, EmptyStringConstant());
Label if_isword16(this), if_isword32(this), return_result(this);
@@ -5194,7 +5169,7 @@ Node* CodeStubAssembler::StringFromCodePoint(Node* codepoint,
Int32Constant(0xDC00));
// codpoint = (trail << 16) | lead;
- codepoint = Word32Or(Word32Shl(trail, Int32Constant(16)), lead);
+ codepoint = Signed(Word32Or(Word32Shl(trail, Int32Constant(16)), lead));
break;
}
}
@@ -5209,12 +5184,10 @@ Node* CodeStubAssembler::StringFromCodePoint(Node* codepoint,
}
BIND(&return_result);
- CSA_ASSERT(this, IsString(var_result.value()));
- return var_result.value();
+ return CAST(var_result.value());
}
-TNode<Number> CodeStubAssembler::StringToNumber(SloppyTNode<Context> context,
- SloppyTNode<String> input) {
+TNode<Number> CodeStubAssembler::StringToNumber(SloppyTNode<String> input) {
CSA_SLOW_ASSERT(this, IsString(input));
Label runtime(this, Label::kDeferred);
Label end(this);
@@ -5226,12 +5199,14 @@ TNode<Number> CodeStubAssembler::StringToNumber(SloppyTNode<Context> context,
GotoIf(IsSetWord32(hash, Name::kDoesNotContainCachedArrayIndexMask),
&runtime);
- var_result = SmiTag(DecodeWordFromWord32<String::ArrayIndexValueBits>(hash));
+ var_result =
+ SmiTag(Signed(DecodeWordFromWord32<String::ArrayIndexValueBits>(hash)));
Goto(&end);
BIND(&runtime);
{
- var_result = CAST(CallRuntime(Runtime::kStringToNumber, context, input));
+ var_result =
+ CAST(CallRuntime(Runtime::kStringToNumber, NoContextConstant(), input));
Goto(&end);
}
@@ -5239,7 +5214,7 @@ TNode<Number> CodeStubAssembler::StringToNumber(SloppyTNode<Context> context,
return var_result;
}
-Node* CodeStubAssembler::NumberToString(Node* context, Node* argument) {
+Node* CodeStubAssembler::NumberToString(Node* argument) {
VARIABLE(result, MachineRepresentation::kTagged);
Label runtime(this, Label::kDeferred), smi(this), done(this, &result);
@@ -5290,7 +5265,8 @@ Node* CodeStubAssembler::NumberToString(Node* context, Node* argument) {
BIND(&runtime);
{
// No cache entry, go to the runtime.
- result.Bind(CallRuntime(Runtime::kNumberToString, context, argument));
+ result.Bind(CallRuntime(Runtime::kNumberToStringSkipCache,
+ NoContextConstant(), argument));
}
Goto(&done);
@@ -5393,7 +5369,7 @@ Node* CodeStubAssembler::NonNumberToNumberOrNumeric(
BIND(&if_inputisstring);
{
// The {input} is a String, use the fast stub to convert it to a Number.
- var_result.Bind(StringToNumber(context, input));
+ var_result.Bind(StringToNumber(input));
Goto(&end);
}
@@ -5525,18 +5501,17 @@ TNode<Number> CodeStubAssembler::ToNumber(SloppyTNode<Context> context,
void CodeStubAssembler::TaggedToNumeric(Node* context, Node* value, Label* done,
Variable* var_numeric) {
- TaggedToNumeric<Feedback::kNone>(context, value, done, var_numeric);
+ TaggedToNumeric(context, value, done, var_numeric, nullptr);
}
void CodeStubAssembler::TaggedToNumericWithFeedback(Node* context, Node* value,
Label* done,
Variable* var_numeric,
Variable* var_feedback) {
- TaggedToNumeric<Feedback::kCollect>(context, value, done, var_numeric,
- var_feedback);
+ DCHECK_NOT_NULL(var_feedback);
+ TaggedToNumeric(context, value, done, var_numeric, var_feedback);
}
-template <CodeStubAssembler::Feedback feedback>
void CodeStubAssembler::TaggedToNumeric(Node* context, Node* value, Label* done,
Variable* var_numeric,
Variable* var_feedback) {
@@ -5551,34 +5526,24 @@ void CodeStubAssembler::TaggedToNumeric(Node* context, Node* value, Label* done,
// {value} is not a Numeric yet.
GotoIf(Word32Equal(instance_type, Int32Constant(ODDBALL_TYPE)), &if_oddball);
var_numeric->Bind(CallBuiltin(Builtins::kNonNumberToNumeric, context, value));
- if (feedback == Feedback::kCollect) {
- var_feedback->Bind(SmiConstant(BinaryOperationFeedback::kAny));
- }
+ OverwriteFeedback(var_feedback, BinaryOperationFeedback::kAny);
Goto(done);
BIND(&if_smi);
- if (feedback == Feedback::kCollect) {
- var_feedback->Bind(SmiConstant(BinaryOperationFeedback::kSignedSmall));
- }
+ OverwriteFeedback(var_feedback, BinaryOperationFeedback::kSignedSmall);
Goto(done);
BIND(&if_heapnumber);
- if (feedback == Feedback::kCollect) {
- var_feedback->Bind(SmiConstant(BinaryOperationFeedback::kNumber));
- }
+ OverwriteFeedback(var_feedback, BinaryOperationFeedback::kNumber);
Goto(done);
BIND(&if_bigint);
- if (feedback == Feedback::kCollect) {
- var_feedback->Bind(SmiConstant(BinaryOperationFeedback::kBigInt));
- }
+ OverwriteFeedback(var_feedback, BinaryOperationFeedback::kBigInt);
Goto(done);
BIND(&if_oddball);
+ OverwriteFeedback(var_feedback, BinaryOperationFeedback::kNumberOrOddball);
var_numeric->Bind(LoadObjectField(value, Oddball::kToNumberOffset));
- if (feedback == Feedback::kCollect) {
- var_feedback->Bind(SmiConstant(BinaryOperationFeedback::kNumberOrOddball));
- }
Goto(done);
}
@@ -5702,7 +5667,7 @@ TNode<String> CodeStubAssembler::ToString(SloppyTNode<Context> context,
Branch(IsHeapNumberMap(input_map), &is_number, &not_heap_number);
BIND(&is_number);
- result.Bind(NumberToString(context, input));
+ result.Bind(NumberToString(input));
Goto(&done);
BIND(&not_heap_number);
@@ -5774,8 +5739,8 @@ Node* CodeStubAssembler::ToSmiIndex(Node* const input, Node* const context,
Branch(IsUndefined(result.value()), &return_zero, &defined);
BIND(&defined);
- result.Bind(ToInteger(context, result.value(),
- CodeStubAssembler::kTruncateMinusZero));
+ result.Bind(ToInteger_Inline(CAST(context), CAST(result.value()),
+ CodeStubAssembler::kTruncateMinusZero));
GotoIfNot(TaggedIsSmi(result.value()), range_error);
CSA_ASSERT(this, TaggedIsSmi(result.value()));
Goto(&negative_check);
@@ -5799,8 +5764,8 @@ Node* CodeStubAssembler::ToSmiLength(Node* input, Node* const context,
Branch(TaggedIsSmi(result.value()), &negative_check, &to_integer);
BIND(&to_integer);
- result.Bind(ToInteger(context, result.value(),
- CodeStubAssembler::kTruncateMinusZero));
+ result.Bind(ToInteger_Inline(CAST(context), CAST(result.value()),
+ CodeStubAssembler::kTruncateMinusZero));
GotoIf(TaggedIsSmi(result.value()), &negative_check);
// result.value() can still be a negative HeapNumber here.
Branch(IsTrue(CallBuiltin(Builtins::kLessThan, context, result.value(),
@@ -5828,6 +5793,16 @@ Node* CodeStubAssembler::ToLength_Inline(Node* const context,
MachineRepresentation::kTagged);
}
+TNode<Number> CodeStubAssembler::ToInteger_Inline(
+ TNode<Context> context, TNode<Object> input, ToIntegerTruncationMode mode) {
+ Builtins::Name builtin = (mode == kNoTruncation)
+ ? Builtins::kToInteger
+ : Builtins::kToInteger_TruncateMinusZero;
+ return CAST(Select(TaggedIsSmi(input), [=] { return input; },
+ [=] { return CallBuiltin(builtin, context, input); },
+ MachineRepresentation::kTagged));
+}
+
TNode<Number> CodeStubAssembler::ToInteger(SloppyTNode<Context> context,
SloppyTNode<Object> input,
ToIntegerTruncationMode mode) {
@@ -5886,6 +5861,7 @@ TNode<Number> CodeStubAssembler::ToInteger(SloppyTNode<Context> context,
}
BIND(&out);
+ if (mode == kTruncateMinusZero) CSA_ASSERT(this, IsNumberNormalized(var_arg));
return CAST(var_arg);
}
@@ -5895,8 +5871,10 @@ TNode<Uint32T> CodeStubAssembler::DecodeWord32(SloppyTNode<Word32T> word32,
Word32And(word32, Int32Constant(mask)), static_cast<int>(shift)));
}
-Node* CodeStubAssembler::DecodeWord(Node* word, uint32_t shift, uint32_t mask) {
- return WordShr(WordAnd(word, IntPtrConstant(mask)), static_cast<int>(shift));
+TNode<UintPtrT> CodeStubAssembler::DecodeWord(SloppyTNode<WordT> word,
+ uint32_t shift, uint32_t mask) {
+ return Unsigned(
+ WordShr(WordAnd(word, IntPtrConstant(mask)), static_cast<int>(shift)));
}
Node* CodeStubAssembler::UpdateWord(Node* word, Node* value, uint32_t shift,
@@ -6187,14 +6165,14 @@ Node* CodeStubAssembler::ComputeIntegerHash(Node* key, Node* seed) {
// See v8::internal::ComputeIntegerHash()
Node* hash = TruncateWordToWord32(key);
hash = Word32Xor(hash, seed);
- hash = Int32Add(Word32Xor(hash, Int32Constant(0xffffffff)),
+ hash = Int32Add(Word32Xor(hash, Int32Constant(0xFFFFFFFF)),
Word32Shl(hash, Int32Constant(15)));
hash = Word32Xor(hash, Word32Shr(hash, Int32Constant(12)));
hash = Int32Add(hash, Word32Shl(hash, Int32Constant(2)));
hash = Word32Xor(hash, Word32Shr(hash, Int32Constant(4)));
hash = Int32Mul(hash, Int32Constant(2057));
hash = Word32Xor(hash, Word32Shr(hash, Int32Constant(16)));
- return Word32And(hash, Int32Constant(0x3fffffff));
+ return Word32And(hash, Int32Constant(0x3FFFFFFF));
}
void CodeStubAssembler::NumberDictionaryLookup(Node* dictionary,
@@ -6391,36 +6369,38 @@ Node* CodeStubAssembler::DescriptorArrayNumberOfEntries(Node* descriptors) {
descriptors, IntPtrConstant(DescriptorArray::kDescriptorLengthIndex));
}
-namespace {
-
-Node* DescriptorNumberToIndex(CodeStubAssembler* a, Node* descriptor_number) {
- Node* descriptor_size = a->Int32Constant(DescriptorArray::kEntrySize);
- Node* index = a->Int32Mul(descriptor_number, descriptor_size);
- return a->ChangeInt32ToIntPtr(index);
+Node* CodeStubAssembler::DescriptorNumberToIndex(
+ SloppyTNode<Uint32T> descriptor_number) {
+ Node* descriptor_size = Int32Constant(DescriptorArray::kEntrySize);
+ Node* index = Int32Mul(descriptor_number, descriptor_size);
+ return ChangeInt32ToIntPtr(index);
}
-} // namespace
-
Node* CodeStubAssembler::DescriptorArrayToKeyIndex(Node* descriptor_number) {
return IntPtrAdd(IntPtrConstant(DescriptorArray::ToKeyIndex(0)),
- DescriptorNumberToIndex(this, descriptor_number));
+ DescriptorNumberToIndex(descriptor_number));
}
Node* CodeStubAssembler::DescriptorArrayGetSortedKeyIndex(
Node* descriptors, Node* descriptor_number) {
- const int details_offset = DescriptorArray::ToDetailsIndex(0) * kPointerSize;
- Node* details = LoadAndUntagToWord32FixedArrayElement(
- descriptors, DescriptorNumberToIndex(this, descriptor_number),
- details_offset);
+ Node* details = DescriptorArrayGetDetails(
+ TNode<DescriptorArray>::UncheckedCast(descriptors),
+ TNode<Uint32T>::UncheckedCast(descriptor_number));
return DecodeWord32<PropertyDetails::DescriptorPointer>(details);
}
Node* CodeStubAssembler::DescriptorArrayGetKey(Node* descriptors,
Node* descriptor_number) {
const int key_offset = DescriptorArray::ToKeyIndex(0) * kPointerSize;
- return LoadFixedArrayElement(descriptors,
- DescriptorNumberToIndex(this, descriptor_number),
- key_offset);
+ return LoadFixedArrayElement(
+ descriptors, DescriptorNumberToIndex(descriptor_number), key_offset);
+}
+
+TNode<Uint32T> CodeStubAssembler::DescriptorArrayGetDetails(
+ TNode<DescriptorArray> descriptors, TNode<Uint32T> descriptor_number) {
+ const int details_offset = DescriptorArray::ToDetailsIndex(0) * kPointerSize;
+ return TNode<Uint32T>::UncheckedCast(LoadAndUntagToWord32FixedArrayElement(
+ descriptors, DescriptorNumberToIndex(descriptor_number), details_offset));
}
void CodeStubAssembler::DescriptorLookupBinary(Node* unique_name,
@@ -6531,13 +6511,13 @@ void CodeStubAssembler::TryLookupProperty(
&if_objectisspecial);
uint32_t mask =
- 1 << Map::kHasNamedInterceptor | 1 << Map::kIsAccessCheckNeeded;
+ Map::HasNamedInterceptorBit::kMask | Map::IsAccessCheckNeededBit::kMask;
CSA_ASSERT(this, Word32BinaryNot(IsSetWord32(LoadMapBitField(map), mask)));
USE(mask);
Node* bit_field3 = LoadMapBitField3(map);
Label if_isfastmap(this), if_isslowmap(this);
- Branch(IsSetWord32<Map::DictionaryMap>(bit_field3), &if_isslowmap,
+ Branch(IsSetWord32<Map::IsDictionaryMapBit>(bit_field3), &if_isslowmap,
&if_isfastmap);
BIND(&if_isfastmap);
{
@@ -6563,7 +6543,8 @@ void CodeStubAssembler::TryLookupProperty(
// Handle interceptors and access checks in runtime.
Node* bit_field = LoadMapBitField(map);
- int mask = 1 << Map::kHasNamedInterceptor | 1 << Map::kIsAccessCheckNeeded;
+ int mask =
+ Map::HasNamedInterceptorBit::kMask | Map::IsAccessCheckNeededBit::kMask;
GotoIf(IsSetWord32(bit_field, mask), if_bailout);
Node* dictionary = LoadSlowProperties(object);
@@ -6618,12 +6599,22 @@ void CodeStubAssembler::LoadPropertyFromFastObject(Node* object, Node* map,
Variable* var_value) {
DCHECK_EQ(MachineRepresentation::kWord32, var_details->rep());
DCHECK_EQ(MachineRepresentation::kTagged, var_value->rep());
- Comment("[ LoadPropertyFromFastObject");
Node* details =
LoadDetailsByKeyIndex<DescriptorArray>(descriptors, name_index);
var_details->Bind(details);
+ LoadPropertyFromFastObject(object, map, descriptors, name_index, details,
+ var_value);
+}
+
+void CodeStubAssembler::LoadPropertyFromFastObject(Node* object, Node* map,
+ Node* descriptors,
+ Node* name_index,
+ Node* details,
+ Variable* var_value) {
+ Comment("[ LoadPropertyFromFastObject");
+
Node* location = DecodeWord32<PropertyDetails::LocationField>(details);
Label if_in_field(this), if_in_descriptor(this), done(this);
@@ -6826,13 +6817,12 @@ Node* CodeStubAssembler::CallGetterIfAccessor(Node* value, Node* details,
// if (!(has_prototype_slot() && !has_non_instance_prototype())) use
// generic property loading mechanism.
- int has_prototype_slot_mask = 1 << Map::kHasPrototypeSlot;
- int has_non_instance_prototype_mask = 1 << Map::kHasNonInstancePrototype;
GotoIfNot(
- Word32Equal(Word32And(LoadMapBitField(receiver_map),
- Int32Constant(has_prototype_slot_mask |
- has_non_instance_prototype_mask)),
- Int32Constant(has_prototype_slot_mask)),
+ Word32Equal(
+ Word32And(LoadMapBitField(receiver_map),
+ Int32Constant(Map::HasPrototypeSlotBit::kMask |
+ Map::HasNonInstancePrototypeBit::kMask)),
+ Int32Constant(Map::HasPrototypeSlotBit::kMask)),
if_bailout);
var_value.Bind(LoadJSFunctionPrototype(receiver, if_bailout));
Goto(&done);
@@ -7061,6 +7051,35 @@ void CodeStubAssembler::TryLookupElement(Node* object, Node* map,
}
}
+void CodeStubAssembler::BranchIfMaybeSpecialIndex(TNode<String> name_string,
+ Label* if_maybe_special_index,
+ Label* if_not_special_index) {
+ // TODO(cwhan.tunz): Implement fast cases more.
+
+ // If a name is empty or too long, it's not a special index
+ // Max length of canonical double: -X.XXXXXXXXXXXXXXXXX-eXXX
+ const int kBufferSize = 24;
+ TNode<Smi> string_length = LoadStringLengthAsSmi(name_string);
+ GotoIf(SmiEqual(string_length, SmiConstant(0)), if_not_special_index);
+ GotoIf(SmiGreaterThan(string_length, SmiConstant(kBufferSize)),
+ if_not_special_index);
+
+ // If the first character of name is not a digit or '-', or we can't match it
+ // to Infinity or NaN, then this is not a special index.
+ TNode<Int32T> first_char = StringCharCodeAt(name_string, IntPtrConstant(0));
+ // If the name starts with '-', it can be a negative index.
+ GotoIf(Word32Equal(first_char, Int32Constant('-')), if_maybe_special_index);
+ // If the name starts with 'I', it can be "Infinity".
+ GotoIf(Word32Equal(first_char, Int32Constant('I')), if_maybe_special_index);
+ // If the name starts with 'N', it can be "NaN".
+ GotoIf(Word32Equal(first_char, Int32Constant('N')), if_maybe_special_index);
+ // Finally, if the first character is not a digit either, then we are sure
+ // that the name is not a special index.
+ GotoIf(Uint32LessThan(first_char, Int32Constant('0')), if_not_special_index);
+ GotoIf(Uint32LessThan(Int32Constant('9'), first_char), if_not_special_index);
+ Goto(if_maybe_special_index);
+}
+
void CodeStubAssembler::TryPrototypeChainLookup(
Node* receiver, Node* key, const LookupInHolder& lookup_property_in_holder,
const LookupInHolder& lookup_element_in_holder, Label* if_end,
@@ -7108,15 +7127,22 @@ void CodeStubAssembler::TryPrototypeChainLookup(
Node* holder_map = var_holder_map.value();
Node* holder_instance_type = var_holder_instance_type.value();
- Label next_proto(this);
+ Label next_proto(this), check_integer_indexed_exotic(this);
lookup_property_in_holder(receiver, var_holder.value(), holder_map,
holder_instance_type, var_unique.value(),
- &next_proto, if_bailout);
- BIND(&next_proto);
+ &check_integer_indexed_exotic, if_bailout);
- // Bailout if it can be an integer indexed exotic case.
- GotoIf(InstanceTypeEqual(holder_instance_type, JS_TYPED_ARRAY_TYPE),
- if_bailout);
+ BIND(&check_integer_indexed_exotic);
+ {
+ // Bailout if it can be an integer indexed exotic case.
+ GotoIfNot(InstanceTypeEqual(holder_instance_type, JS_TYPED_ARRAY_TYPE),
+ &next_proto);
+ GotoIfNot(IsString(var_unique.value()), &next_proto);
+ BranchIfMaybeSpecialIndex(CAST(var_unique.value()), if_bailout,
+ &next_proto);
+ }
+
+ BIND(&next_proto);
Node* proto = LoadMapPrototype(holder_map);
@@ -7192,8 +7218,8 @@ Node* CodeStubAssembler::HasInPrototypeChain(Node* context, Node* object,
GotoIf(InstanceTypeEqual(object_instance_type, JS_PROXY_TYPE),
&return_runtime);
Node* object_bitfield = LoadMapBitField(object_map);
- int mask =
- 1 << Map::kHasNamedInterceptor | 1 << Map::kIsAccessCheckNeeded;
+ int mask = Map::HasNamedInterceptorBit::kMask |
+ Map::IsAccessCheckNeededBit::kMask;
Branch(IsSetWord32(object_bitfield, mask), &return_runtime,
&if_objectisdirect);
}
@@ -7252,12 +7278,12 @@ Node* CodeStubAssembler::OrdinaryHasInstance(Node* context, Node* callable,
// Goto runtime if {callable} is not a constructor or has
// a non-instance "prototype".
Node* callable_bitfield = LoadMapBitField(callable_map);
- GotoIfNot(
- Word32Equal(Word32And(callable_bitfield,
- Int32Constant((1 << Map::kHasNonInstancePrototype) |
- (1 << Map::kIsConstructor))),
- Int32Constant(1 << Map::kIsConstructor)),
- &return_runtime);
+ GotoIfNot(Word32Equal(
+ Word32And(callable_bitfield,
+ Int32Constant(Map::HasNonInstancePrototypeBit::kMask |
+ Map::IsConstructorBit::kMask)),
+ Int32Constant(Map::IsConstructorBit::kMask)),
+ &return_runtime);
// Get the "prototype" (or initial map) of the {callable}.
Node* callable_prototype =
@@ -7326,7 +7352,7 @@ Node* CodeStubAssembler::ElementOffsetFromIndex(Node* index_node,
? index_node
: ((element_size_shift > 0)
? WordShl(index_node, IntPtrConstant(element_size_shift))
- : WordShr(index_node, IntPtrConstant(-element_size_shift)));
+ : WordSar(index_node, IntPtrConstant(-element_size_shift)));
return IntPtrAdd(IntPtrConstant(base_size), shifted_index);
}
@@ -7377,8 +7403,22 @@ void CodeStubAssembler::ReportFeedbackUpdate(
#endif // V8_TRACE_FEEDBACK_UPDATES
}
+void CodeStubAssembler::OverwriteFeedback(Variable* existing_feedback,
+ int new_feedback) {
+ if (existing_feedback == nullptr) return;
+ existing_feedback->Bind(SmiConstant(new_feedback));
+}
+
+void CodeStubAssembler::CombineFeedback(Variable* existing_feedback,
+ int feedback) {
+ if (existing_feedback == nullptr) return;
+ existing_feedback->Bind(
+ SmiOr(existing_feedback->value(), SmiConstant(feedback)));
+}
+
void CodeStubAssembler::CombineFeedback(Variable* existing_feedback,
Node* feedback) {
+ if (existing_feedback == nullptr) return;
existing_feedback->Bind(SmiOr(existing_feedback->value(), feedback));
}
@@ -7524,15 +7564,16 @@ Node* CodeStubAssembler::EmitKeyedSloppyArguments(Node* receiver, Node* key,
return var_result.value();
}
-Node* CodeStubAssembler::LoadScriptContext(Node* context, int context_index) {
- Node* native_context = LoadNativeContext(context);
- Node* script_context_table =
- LoadContextElement(native_context, Context::SCRIPT_CONTEXT_TABLE_INDEX);
+TNode<Context> CodeStubAssembler::LoadScriptContext(
+ TNode<Context> context, TNode<IntPtrT> context_index) {
+ TNode<Context> native_context = LoadNativeContext(context);
+ TNode<ScriptContextTable> script_context_table = CAST(
+ LoadContextElement(native_context, Context::SCRIPT_CONTEXT_TABLE_INDEX));
- int offset =
- ScriptContextTable::GetContextOffset(context_index) - kHeapObjectTag;
- return Load(MachineType::AnyTagged(), script_context_table,
- IntPtrConstant(offset));
+ Node* script_context = LoadFixedArrayElement(
+ script_context_table, context_index,
+ ScriptContextTable::kFirstContextSlotIndex * kPointerSize);
+ return CAST(script_context);
}
namespace {
@@ -7567,7 +7608,7 @@ void CodeStubAssembler::StoreElement(Node* elements, ElementsKind kind,
if (IsFixedTypedArrayElementsKind(kind)) {
if (kind == UINT8_CLAMPED_ELEMENTS) {
CSA_ASSERT(this,
- Word32Equal(value, Word32And(Int32Constant(0xff), value)));
+ Word32Equal(value, Word32And(Int32Constant(0xFF), value)));
}
Node* offset = ElementOffsetFromIndex(index, kind, mode, 0);
MachineRepresentation rep = ElementsKindToMachineRepresentation(kind);
@@ -8029,8 +8070,8 @@ Node* CodeStubAssembler::BuildFastLoop(
? MachineType::PointerRepresentation()
: MachineRepresentation::kTaggedSigned;
VARIABLE(var, index_rep, start_index);
- VariableList vars_copy(vars, zone());
- vars_copy.Add(&var, zone());
+ VariableList vars_copy(vars.begin(), vars.end(), zone());
+ vars_copy.push_back(&var);
Label loop(this, vars_copy);
Label after_loop(this);
// Introduce an explicit second check of the termination condition before the
@@ -8135,109 +8176,86 @@ void CodeStubAssembler::InitializeFieldsWithRoot(
CodeStubAssembler::IndexAdvanceMode::kPre);
}
-void CodeStubAssembler::BranchIfNumericRelationalComparison(
- Operation op, Node* lhs, Node* rhs, Label* if_true, Label* if_false) {
- CSA_SLOW_ASSERT(this, IsNumber(lhs));
- CSA_SLOW_ASSERT(this, IsNumber(rhs));
+void CodeStubAssembler::BranchIfNumberRelationalComparison(
+ Operation op, Node* left, Node* right, Label* if_true, Label* if_false) {
+ CSA_SLOW_ASSERT(this, IsNumber(left));
+ CSA_SLOW_ASSERT(this, IsNumber(right));
- Label end(this);
- VARIABLE(result, MachineRepresentation::kTagged);
-
- // Shared entry for floating point comparison.
- Label do_fcmp(this);
- VARIABLE(var_fcmp_lhs, MachineRepresentation::kFloat64);
- VARIABLE(var_fcmp_rhs, MachineRepresentation::kFloat64);
+ Label do_float_comparison(this);
+ TVARIABLE(Float64T, var_left_float);
+ TVARIABLE(Float64T, var_right_float);
- // Check if the {lhs} is a Smi or a HeapObject.
- Label if_lhsissmi(this), if_lhsisnotsmi(this);
- Branch(TaggedIsSmi(lhs), &if_lhsissmi, &if_lhsisnotsmi);
+ Label if_left_smi(this), if_left_not_smi(this);
+ Branch(TaggedIsSmi(left), &if_left_smi, &if_left_not_smi);
- BIND(&if_lhsissmi);
+ BIND(&if_left_smi);
{
- // Check if {rhs} is a Smi or a HeapObject.
- Label if_rhsissmi(this), if_rhsisnotsmi(this);
- Branch(TaggedIsSmi(rhs), &if_rhsissmi, &if_rhsisnotsmi);
+ Label if_right_not_smi(this);
+ GotoIfNot(TaggedIsSmi(right), &if_right_not_smi);
- BIND(&if_rhsissmi);
- {
- // Both {lhs} and {rhs} are Smi, so just perform a fast Smi comparison.
- switch (op) {
- case Operation::kLessThan:
- BranchIfSmiLessThan(lhs, rhs, if_true, if_false);
- break;
- case Operation::kLessThanOrEqual:
- BranchIfSmiLessThanOrEqual(lhs, rhs, if_true, if_false);
- break;
- case Operation::kGreaterThan:
- BranchIfSmiLessThan(rhs, lhs, if_true, if_false);
- break;
- case Operation::kGreaterThanOrEqual:
- BranchIfSmiLessThanOrEqual(rhs, lhs, if_true, if_false);
- break;
- default:
- UNREACHABLE();
- }
+ // Both {left} and {right} are Smi, so just perform a fast Smi comparison.
+ switch (op) {
+ case Operation::kLessThan:
+ BranchIfSmiLessThan(left, right, if_true, if_false);
+ break;
+ case Operation::kLessThanOrEqual:
+ BranchIfSmiLessThanOrEqual(left, right, if_true, if_false);
+ break;
+ case Operation::kGreaterThan:
+ BranchIfSmiLessThan(right, left, if_true, if_false);
+ break;
+ case Operation::kGreaterThanOrEqual:
+ BranchIfSmiLessThanOrEqual(right, left, if_true, if_false);
+ break;
+ default:
+ UNREACHABLE();
}
- BIND(&if_rhsisnotsmi);
+ BIND(&if_right_not_smi);
{
- CSA_ASSERT(this, IsHeapNumber(rhs));
- // Convert the {lhs} and {rhs} to floating point values, and
- // perform a floating point comparison.
- var_fcmp_lhs.Bind(SmiToFloat64(lhs));
- var_fcmp_rhs.Bind(LoadHeapNumberValue(rhs));
- Goto(&do_fcmp);
+ CSA_ASSERT(this, IsHeapNumber(right));
+ var_left_float = SmiToFloat64(left);
+ var_right_float = LoadHeapNumberValue(right);
+ Goto(&do_float_comparison);
}
}
- BIND(&if_lhsisnotsmi);
+ BIND(&if_left_not_smi);
{
- CSA_ASSERT(this, IsHeapNumber(lhs));
+ CSA_ASSERT(this, IsHeapNumber(left));
+ var_left_float = LoadHeapNumberValue(left);
- // Check if {rhs} is a Smi or a HeapObject.
- Label if_rhsissmi(this), if_rhsisnotsmi(this);
- Branch(TaggedIsSmi(rhs), &if_rhsissmi, &if_rhsisnotsmi);
+ Label if_right_not_smi(this);
+ GotoIfNot(TaggedIsSmi(right), &if_right_not_smi);
+ var_right_float = SmiToFloat64(right);
+ Goto(&do_float_comparison);
- BIND(&if_rhsissmi);
+ BIND(&if_right_not_smi);
{
- // Convert the {lhs} and {rhs} to floating point values, and
- // perform a floating point comparison.
- var_fcmp_lhs.Bind(LoadHeapNumberValue(lhs));
- var_fcmp_rhs.Bind(SmiToFloat64(rhs));
- Goto(&do_fcmp);
- }
-
- BIND(&if_rhsisnotsmi);
- {
- CSA_ASSERT(this, IsHeapNumber(rhs));
-
- // Convert the {lhs} and {rhs} to floating point values, and
- // perform a floating point comparison.
- var_fcmp_lhs.Bind(LoadHeapNumberValue(lhs));
- var_fcmp_rhs.Bind(LoadHeapNumberValue(rhs));
- Goto(&do_fcmp);
+ CSA_ASSERT(this, IsHeapNumber(right));
+ var_right_float = LoadHeapNumberValue(right);
+ Goto(&do_float_comparison);
}
}
- BIND(&do_fcmp);
+ BIND(&do_float_comparison);
{
- // Load the {lhs} and {rhs} floating point values.
- Node* lhs = var_fcmp_lhs.value();
- Node* rhs = var_fcmp_rhs.value();
-
- // Perform a fast floating point comparison.
switch (op) {
case Operation::kLessThan:
- Branch(Float64LessThan(lhs, rhs), if_true, if_false);
+ Branch(Float64LessThan(var_left_float, var_right_float), if_true,
+ if_false);
break;
case Operation::kLessThanOrEqual:
- Branch(Float64LessThanOrEqual(lhs, rhs), if_true, if_false);
+ Branch(Float64LessThanOrEqual(var_left_float, var_right_float), if_true,
+ if_false);
break;
case Operation::kGreaterThan:
- Branch(Float64GreaterThan(lhs, rhs), if_true, if_false);
+ Branch(Float64GreaterThan(var_left_float, var_right_float), if_true,
+ if_false);
break;
case Operation::kGreaterThanOrEqual:
- Branch(Float64GreaterThanOrEqual(lhs, rhs), if_true, if_false);
+ Branch(Float64GreaterThanOrEqual(var_left_float, var_right_float),
+ if_true, if_false);
break;
default:
UNREACHABLE();
@@ -8245,11 +8263,11 @@ void CodeStubAssembler::BranchIfNumericRelationalComparison(
}
}
-void CodeStubAssembler::GotoIfNumericGreaterThanOrEqual(Node* lhs, Node* rhs,
- Label* if_true) {
+void CodeStubAssembler::GotoIfNumberGreaterThanOrEqual(Node* left, Node* right,
+ Label* if_true) {
Label if_false(this);
- BranchIfNumericRelationalComparison(Operation::kGreaterThanOrEqual, lhs, rhs,
- if_true, &if_false);
+ BranchIfNumberRelationalComparison(Operation::kGreaterThanOrEqual, left,
+ right, if_true, &if_false);
BIND(&if_false);
}
@@ -8271,423 +8289,354 @@ Operation Reverse(Operation op) {
}
} // anonymous namespace
-Node* CodeStubAssembler::RelationalComparison(Operation op, Node* lhs,
- Node* rhs, Node* context,
+Node* CodeStubAssembler::RelationalComparison(Operation op, Node* left,
+ Node* right, Node* context,
Variable* var_type_feedback) {
- Label return_true(this), return_false(this), end(this);
- VARIABLE(result, MachineRepresentation::kTagged);
-
- // Shared entry for floating point comparison.
- Label do_fcmp(this);
- VARIABLE(var_fcmp_lhs, MachineRepresentation::kFloat64);
- VARIABLE(var_fcmp_rhs, MachineRepresentation::kFloat64);
+ Label return_true(this), return_false(this), do_float_comparison(this),
+ end(this);
+ TVARIABLE(Oddball, var_result); // Actually only "true" or "false".
+ TVARIABLE(Float64T, var_left_float);
+ TVARIABLE(Float64T, var_right_float);
// We might need to loop several times due to ToPrimitive and/or ToNumeric
// conversions.
- VARIABLE(var_lhs, MachineRepresentation::kTagged, lhs);
- VARIABLE(var_rhs, MachineRepresentation::kTagged, rhs);
- VariableList loop_variable_list({&var_lhs, &var_rhs}, zone());
+ VARIABLE(var_left, MachineRepresentation::kTagged, left);
+ VARIABLE(var_right, MachineRepresentation::kTagged, right);
+ VariableList loop_variable_list({&var_left, &var_right}, zone());
if (var_type_feedback != nullptr) {
// Initialize the type feedback to None. The current feedback is combined
// with the previous feedback.
var_type_feedback->Bind(SmiConstant(CompareOperationFeedback::kNone));
- loop_variable_list.Add(var_type_feedback, zone());
+ loop_variable_list.push_back(var_type_feedback);
}
Label loop(this, loop_variable_list);
Goto(&loop);
BIND(&loop);
{
- // Load the current {lhs} and {rhs} values.
- lhs = var_lhs.value();
- rhs = var_rhs.value();
+ left = var_left.value();
+ right = var_right.value();
- // Check if the {lhs} is a Smi or a HeapObject.
- Label if_lhsissmi(this), if_lhsisnotsmi(this);
- Branch(TaggedIsSmi(lhs), &if_lhsissmi, &if_lhsisnotsmi);
+ Label if_left_smi(this), if_left_not_smi(this);
+ Branch(TaggedIsSmi(left), &if_left_smi, &if_left_not_smi);
- BIND(&if_lhsissmi);
+ BIND(&if_left_smi);
{
- Label if_rhsissmi(this), if_rhsisheapnumber(this),
- if_rhsisbigint(this, Label::kDeferred),
- if_rhsisnotnumeric(this, Label::kDeferred);
- GotoIf(TaggedIsSmi(rhs), &if_rhsissmi);
- Node* rhs_map = LoadMap(rhs);
- GotoIf(IsHeapNumberMap(rhs_map), &if_rhsisheapnumber);
- Node* rhs_instance_type = LoadMapInstanceType(rhs_map);
- Branch(IsBigIntInstanceType(rhs_instance_type), &if_rhsisbigint,
- &if_rhsisnotnumeric);
+ Label if_right_smi(this), if_right_heapnumber(this),
+ if_right_bigint(this, Label::kDeferred),
+ if_right_not_numeric(this, Label::kDeferred);
+ GotoIf(TaggedIsSmi(right), &if_right_smi);
+ Node* right_map = LoadMap(right);
+ GotoIf(IsHeapNumberMap(right_map), &if_right_heapnumber);
+ Node* right_instance_type = LoadMapInstanceType(right_map);
+ Branch(IsBigIntInstanceType(right_instance_type), &if_right_bigint,
+ &if_right_not_numeric);
- BIND(&if_rhsissmi);
+ BIND(&if_right_smi);
{
- // Both {lhs} and {rhs} are Smi, so just perform a fast Smi comparison.
- if (var_type_feedback != nullptr) {
- CombineFeedback(var_type_feedback,
- SmiConstant(CompareOperationFeedback::kSignedSmall));
- }
+ CombineFeedback(var_type_feedback,
+ CompareOperationFeedback::kSignedSmall);
switch (op) {
case Operation::kLessThan:
- BranchIfSmiLessThan(lhs, rhs, &return_true, &return_false);
+ BranchIfSmiLessThan(left, right, &return_true, &return_false);
break;
case Operation::kLessThanOrEqual:
- BranchIfSmiLessThanOrEqual(lhs, rhs, &return_true, &return_false);
+ BranchIfSmiLessThanOrEqual(left, right, &return_true,
+ &return_false);
break;
case Operation::kGreaterThan:
- BranchIfSmiLessThan(rhs, lhs, &return_true, &return_false);
+ BranchIfSmiLessThan(right, left, &return_true, &return_false);
break;
case Operation::kGreaterThanOrEqual:
- BranchIfSmiLessThanOrEqual(rhs, lhs, &return_true, &return_false);
+ BranchIfSmiLessThanOrEqual(right, left, &return_true,
+ &return_false);
break;
default:
UNREACHABLE();
}
}
- BIND(&if_rhsisheapnumber);
+ BIND(&if_right_heapnumber);
{
- // Convert the {lhs} and {rhs} to floating point values, and
- // perform a floating point comparison.
- if (var_type_feedback != nullptr) {
- CombineFeedback(var_type_feedback,
- SmiConstant(CompareOperationFeedback::kNumber));
- }
- var_fcmp_lhs.Bind(SmiToFloat64(lhs));
- var_fcmp_rhs.Bind(LoadHeapNumberValue(rhs));
- Goto(&do_fcmp);
+ CombineFeedback(var_type_feedback, CompareOperationFeedback::kNumber);
+ var_left_float = SmiToFloat64(left);
+ var_right_float = LoadHeapNumberValue(right);
+ Goto(&do_float_comparison);
}
- BIND(&if_rhsisbigint);
+ BIND(&if_right_bigint);
{
- // The {lhs} is a Smi and {rhs} is a BigInt.
- if (var_type_feedback != nullptr) {
- var_type_feedback->Bind(SmiConstant(CompareOperationFeedback::kAny));
- }
- result.Bind(CallRuntime(Runtime::kBigIntCompareToNumber,
- NoContextConstant(), SmiConstant(Reverse(op)),
- rhs, lhs));
+ OverwriteFeedback(var_type_feedback, CompareOperationFeedback::kAny);
+ var_result = CAST(CallRuntime(Runtime::kBigIntCompareToNumber,
+ NoContextConstant(),
+ SmiConstant(Reverse(op)), right, left));
Goto(&end);
}
- BIND(&if_rhsisnotnumeric);
+ BIND(&if_right_not_numeric);
{
- // The {lhs} is a Smi and {rhs} is not a Numeric.
- if (var_type_feedback != nullptr) {
- var_type_feedback->Bind(SmiConstant(CompareOperationFeedback::kAny));
- }
- // Convert the {rhs} to a Numeric; we don't need to perform the
- // dedicated ToPrimitive(rhs, hint Number) operation, as the
- // ToNumeric(rhs) will by itself already invoke ToPrimitive with
+ OverwriteFeedback(var_type_feedback, CompareOperationFeedback::kAny);
+ // Convert {right} to a Numeric; we don't need to perform the
+ // dedicated ToPrimitive(right, hint Number) operation, as the
+ // ToNumeric(right) will by itself already invoke ToPrimitive with
// a Number hint.
- var_rhs.Bind(CallBuiltin(Builtins::kNonNumberToNumeric, context, rhs));
+ var_right.Bind(
+ CallBuiltin(Builtins::kNonNumberToNumeric, context, right));
Goto(&loop);
}
}
- BIND(&if_lhsisnotsmi);
+ BIND(&if_left_not_smi);
{
- Node* lhs_map = LoadMap(lhs);
+ Node* left_map = LoadMap(left);
- // Check if {rhs} is a Smi or a HeapObject.
- Label if_rhsissmi(this), if_rhsisnotsmi(this);
- Branch(TaggedIsSmi(rhs), &if_rhsissmi, &if_rhsisnotsmi);
+ Label if_right_smi(this), if_right_not_smi(this);
+ Branch(TaggedIsSmi(right), &if_right_smi, &if_right_not_smi);
- BIND(&if_rhsissmi);
+ BIND(&if_right_smi);
{
- Label if_lhsisheapnumber(this), if_lhsisbigint(this, Label::kDeferred),
- if_lhsisnotnumeric(this, Label::kDeferred);
- GotoIf(IsHeapNumberMap(lhs_map), &if_lhsisheapnumber);
- Node* lhs_instance_type = LoadMapInstanceType(lhs_map);
- Branch(IsBigIntInstanceType(lhs_instance_type), &if_lhsisbigint,
- &if_lhsisnotnumeric);
-
- BIND(&if_lhsisheapnumber);
+ Label if_left_heapnumber(this), if_left_bigint(this, Label::kDeferred),
+ if_left_not_numeric(this, Label::kDeferred);
+ GotoIf(IsHeapNumberMap(left_map), &if_left_heapnumber);
+ Node* left_instance_type = LoadMapInstanceType(left_map);
+ Branch(IsBigIntInstanceType(left_instance_type), &if_left_bigint,
+ &if_left_not_numeric);
+
+ BIND(&if_left_heapnumber);
{
- // Convert the {lhs} and {rhs} to floating point values, and
- // perform a floating point comparison.
- if (var_type_feedback != nullptr) {
- CombineFeedback(var_type_feedback,
- SmiConstant(CompareOperationFeedback::kNumber));
- }
- var_fcmp_lhs.Bind(LoadHeapNumberValue(lhs));
- var_fcmp_rhs.Bind(SmiToFloat64(rhs));
- Goto(&do_fcmp);
+ CombineFeedback(var_type_feedback, CompareOperationFeedback::kNumber);
+ var_left_float = LoadHeapNumberValue(left);
+ var_right_float = SmiToFloat64(right);
+ Goto(&do_float_comparison);
}
- BIND(&if_lhsisbigint);
+ BIND(&if_left_bigint);
{
- if (var_type_feedback != nullptr) {
- var_type_feedback->Bind(
- SmiConstant(CompareOperationFeedback::kAny));
- }
- result.Bind(CallRuntime(Runtime::kBigIntCompareToNumber,
- NoContextConstant(), SmiConstant(op), lhs,
- rhs));
+ OverwriteFeedback(var_type_feedback, CompareOperationFeedback::kAny);
+ var_result = CAST(CallRuntime(Runtime::kBigIntCompareToNumber,
+ NoContextConstant(), SmiConstant(op),
+ left, right));
Goto(&end);
}
- BIND(&if_lhsisnotnumeric);
+ BIND(&if_left_not_numeric);
{
- // The {lhs} is not a Numeric and {rhs} is an Smi.
- if (var_type_feedback != nullptr) {
- var_type_feedback->Bind(
- SmiConstant(CompareOperationFeedback::kAny));
- }
- // Convert the {lhs} to a Numeric; we don't need to perform the
- // dedicated ToPrimitive(lhs, hint Number) operation, as the
- // ToNumeric(lhs) will by itself already invoke ToPrimitive with
+ OverwriteFeedback(var_type_feedback, CompareOperationFeedback::kAny);
+ // Convert {left} to a Numeric; we don't need to perform the
+ // dedicated ToPrimitive(left, hint Number) operation, as the
+ // ToNumeric(left) will by itself already invoke ToPrimitive with
// a Number hint.
- var_lhs.Bind(
- CallBuiltin(Builtins::kNonNumberToNumeric, context, lhs));
+ var_left.Bind(
+ CallBuiltin(Builtins::kNonNumberToNumeric, context, left));
Goto(&loop);
}
}
- BIND(&if_rhsisnotsmi);
+ BIND(&if_right_not_smi);
{
- // Load the map of {rhs}.
- Node* rhs_map = LoadMap(rhs);
+ Node* right_map = LoadMap(right);
- // Further analyze {lhs}.
- Label if_lhsisheapnumber(this), if_lhsisbigint(this, Label::kDeferred),
- if_lhsisstring(this), if_lhsisother(this, Label::kDeferred);
- GotoIf(IsHeapNumberMap(lhs_map), &if_lhsisheapnumber);
- Node* lhs_instance_type = LoadMapInstanceType(lhs_map);
- GotoIf(IsBigIntInstanceType(lhs_instance_type), &if_lhsisbigint);
- Branch(IsStringInstanceType(lhs_instance_type), &if_lhsisstring,
- &if_lhsisother);
+ Label if_left_heapnumber(this), if_left_bigint(this, Label::kDeferred),
+ if_left_string(this), if_left_other(this, Label::kDeferred);
+ GotoIf(IsHeapNumberMap(left_map), &if_left_heapnumber);
+ Node* left_instance_type = LoadMapInstanceType(left_map);
+ GotoIf(IsBigIntInstanceType(left_instance_type), &if_left_bigint);
+ Branch(IsStringInstanceType(left_instance_type), &if_left_string,
+ &if_left_other);
- BIND(&if_lhsisheapnumber);
+ BIND(&if_left_heapnumber);
{
- // Further inspect {rhs}.
- Label if_rhsisheapnumber(this),
- if_rhsisbigint(this, Label::kDeferred),
- if_rhsisnotnumeric(this, Label::kDeferred);
- GotoIf(WordEqual(rhs_map, lhs_map), &if_rhsisheapnumber);
- Node* rhs_instance_type = LoadMapInstanceType(rhs_map);
- Branch(IsBigIntInstanceType(rhs_instance_type), &if_rhsisbigint,
- &if_rhsisnotnumeric);
-
- BIND(&if_rhsisheapnumber);
+ Label if_right_heapnumber(this),
+ if_right_bigint(this, Label::kDeferred),
+ if_right_not_numeric(this, Label::kDeferred);
+ GotoIf(WordEqual(right_map, left_map), &if_right_heapnumber);
+ Node* right_instance_type = LoadMapInstanceType(right_map);
+ Branch(IsBigIntInstanceType(right_instance_type), &if_right_bigint,
+ &if_right_not_numeric);
+
+ BIND(&if_right_heapnumber);
{
- // Convert the {lhs} and {rhs} to floating point values, and
- // perform a floating point comparison.
- if (var_type_feedback != nullptr) {
- CombineFeedback(var_type_feedback,
- SmiConstant(CompareOperationFeedback::kNumber));
- }
- var_fcmp_lhs.Bind(LoadHeapNumberValue(lhs));
- var_fcmp_rhs.Bind(LoadHeapNumberValue(rhs));
- Goto(&do_fcmp);
+ CombineFeedback(var_type_feedback,
+ CompareOperationFeedback::kNumber);
+ var_left_float = LoadHeapNumberValue(left);
+ var_right_float = LoadHeapNumberValue(right);
+ Goto(&do_float_comparison);
}
- BIND(&if_rhsisbigint);
+ BIND(&if_right_bigint);
{
- if (var_type_feedback != nullptr) {
- var_type_feedback->Bind(
- SmiConstant(CompareOperationFeedback::kAny));
- }
- result.Bind(CallRuntime(Runtime::kBigIntCompareToNumber,
- NoContextConstant(),
- SmiConstant(Reverse(op)), rhs, lhs));
+ OverwriteFeedback(var_type_feedback,
+ CompareOperationFeedback::kAny);
+ var_result = CAST(CallRuntime(
+ Runtime::kBigIntCompareToNumber, NoContextConstant(),
+ SmiConstant(Reverse(op)), right, left));
Goto(&end);
}
- BIND(&if_rhsisnotnumeric);
+ BIND(&if_right_not_numeric);
{
- // The {lhs} is a HeapNumber and {rhs} is not a Numeric.
- if (var_type_feedback != nullptr) {
- var_type_feedback->Bind(
- SmiConstant(CompareOperationFeedback::kAny));
- }
- // Convert the {rhs} to a Numeric; we don't need to perform
- // dedicated ToPrimitive(rhs, hint Number) operation, as the
- // ToNumeric(rhs) will by itself already invoke ToPrimitive with
+ OverwriteFeedback(var_type_feedback,
+ CompareOperationFeedback::kAny);
+ // Convert {right} to a Numeric; we don't need to perform
+ // dedicated ToPrimitive(right, hint Number) operation, as the
+ // ToNumeric(right) will by itself already invoke ToPrimitive with
// a Number hint.
- var_rhs.Bind(
- CallBuiltin(Builtins::kNonNumberToNumeric, context, rhs));
+ var_right.Bind(
+ CallBuiltin(Builtins::kNonNumberToNumeric, context, right));
Goto(&loop);
}
}
- BIND(&if_lhsisbigint);
+ BIND(&if_left_bigint);
{
- if (var_type_feedback != nullptr) {
- var_type_feedback->Bind(
- SmiConstant(CompareOperationFeedback::kAny));
- }
-
- Label if_rhsisheapnumber(this), if_rhsisbigint(this),
- if_rhsisnotnumeric(this);
- GotoIf(IsHeapNumberMap(rhs_map), &if_rhsisheapnumber);
- Node* rhs_instance_type = LoadMapInstanceType(rhs_map);
- Branch(IsBigIntInstanceType(rhs_instance_type), &if_rhsisbigint,
- &if_rhsisnotnumeric);
-
- BIND(&if_rhsisheapnumber);
+ Label if_right_heapnumber(this), if_right_bigint(this),
+ if_right_not_numeric(this);
+ GotoIf(IsHeapNumberMap(right_map), &if_right_heapnumber);
+ Node* right_instance_type = LoadMapInstanceType(right_map);
+ Branch(IsBigIntInstanceType(right_instance_type), &if_right_bigint,
+ &if_right_not_numeric);
+
+ BIND(&if_right_heapnumber);
{
- result.Bind(CallRuntime(Runtime::kBigIntCompareToNumber,
- NoContextConstant(), SmiConstant(op), lhs,
- rhs));
+ OverwriteFeedback(var_type_feedback,
+ CompareOperationFeedback::kAny);
+ var_result = CAST(CallRuntime(Runtime::kBigIntCompareToNumber,
+ NoContextConstant(), SmiConstant(op),
+ left, right));
Goto(&end);
}
- BIND(&if_rhsisbigint);
+ BIND(&if_right_bigint);
{
- result.Bind(CallRuntime(Runtime::kBigIntCompareToBigInt,
- NoContextConstant(), SmiConstant(op), lhs,
- rhs));
+ CombineFeedback(var_type_feedback,
+ CompareOperationFeedback::kBigInt);
+ var_result = CAST(CallRuntime(Runtime::kBigIntCompareToBigInt,
+ NoContextConstant(), SmiConstant(op),
+ left, right));
Goto(&end);
}
- BIND(&if_rhsisnotnumeric);
+ BIND(&if_right_not_numeric);
{
- // Convert the {rhs} to a Numeric; we don't need to perform
- // dedicated ToPrimitive(rhs, hint Number) operation, as the
- // ToNumeric(rhs) will by itself already invoke ToPrimitive with
+ OverwriteFeedback(var_type_feedback,
+ CompareOperationFeedback::kAny);
+ // Convert {right} to a Numeric; we don't need to perform
+ // dedicated ToPrimitive(right, hint Number) operation, as the
+ // ToNumeric(right) will by itself already invoke ToPrimitive with
// a Number hint.
- var_rhs.Bind(
- CallBuiltin(Builtins::kNonNumberToNumeric, context, rhs));
+ var_right.Bind(
+ CallBuiltin(Builtins::kNonNumberToNumeric, context, right));
Goto(&loop);
}
}
- BIND(&if_lhsisstring);
+ BIND(&if_left_string);
{
- // Load the instance type of {rhs}.
- Node* rhs_instance_type = LoadMapInstanceType(rhs_map);
-
- // Check if {rhs} is also a String.
- Label if_rhsisstring(this, Label::kDeferred),
- if_rhsisnotstring(this, Label::kDeferred);
- Branch(IsStringInstanceType(rhs_instance_type), &if_rhsisstring,
- &if_rhsisnotstring);
-
- BIND(&if_rhsisstring);
- {
- // Both {lhs} and {rhs} are strings.
- if (var_type_feedback != nullptr) {
- CombineFeedback(var_type_feedback,
- SmiConstant(CompareOperationFeedback::kString));
- }
- switch (op) {
- case Operation::kLessThan:
- result.Bind(
- CallBuiltin(Builtins::kStringLessThan, context, lhs, rhs));
- Goto(&end);
- break;
- case Operation::kLessThanOrEqual:
- result.Bind(CallBuiltin(Builtins::kStringLessThanOrEqual,
- context, lhs, rhs));
- Goto(&end);
- break;
- case Operation::kGreaterThan:
- result.Bind(CallBuiltin(Builtins::kStringGreaterThan, context,
- lhs, rhs));
- Goto(&end);
- break;
- case Operation::kGreaterThanOrEqual:
- result.Bind(CallBuiltin(Builtins::kStringGreaterThanOrEqual,
- context, lhs, rhs));
- Goto(&end);
- break;
- default:
- UNREACHABLE();
- }
+ Node* right_instance_type = LoadMapInstanceType(right_map);
+
+ Label if_right_not_string(this, Label::kDeferred);
+ GotoIfNot(IsStringInstanceType(right_instance_type),
+ &if_right_not_string);
+
+ // Both {left} and {right} are strings.
+ CombineFeedback(var_type_feedback, CompareOperationFeedback::kString);
+ Builtins::Name builtin;
+ switch (op) {
+ case Operation::kLessThan:
+ builtin = Builtins::kStringLessThan;
+ break;
+ case Operation::kLessThanOrEqual:
+ builtin = Builtins::kStringLessThanOrEqual;
+ break;
+ case Operation::kGreaterThan:
+ builtin = Builtins::kStringGreaterThan;
+ break;
+ case Operation::kGreaterThanOrEqual:
+ builtin = Builtins::kStringGreaterThanOrEqual;
+ break;
+ default:
+ UNREACHABLE();
}
+ var_result = CAST(CallBuiltin(builtin, context, left, right));
+ Goto(&end);
- BIND(&if_rhsisnotstring);
+ BIND(&if_right_not_string);
{
- // The {lhs} is a String and {rhs} is not a String.
- if (var_type_feedback != nullptr) {
- var_type_feedback->Bind(
- SmiConstant(CompareOperationFeedback::kAny));
- }
- // The {lhs} is a String, while {rhs} isn't. So we call
- // ToPrimitive(rhs, hint Number) if {rhs} is a receiver, or
- // ToNumeric(lhs) and then ToNumeric(rhs) in the other cases.
+ OverwriteFeedback(var_type_feedback,
+ CompareOperationFeedback::kAny);
+ // {left} is a String, while {right} isn't. So we call
+ // ToPrimitive(right, hint Number) if {right} is a receiver, or
+ // ToNumeric(left) and then ToNumeric(right) in the other cases.
STATIC_ASSERT(LAST_JS_RECEIVER_TYPE == LAST_TYPE);
- Label if_rhsisreceiver(this, Label::kDeferred),
- if_rhsisnotreceiver(this, Label::kDeferred);
- Branch(IsJSReceiverInstanceType(rhs_instance_type),
- &if_rhsisreceiver, &if_rhsisnotreceiver);
+ Label if_right_receiver(this, Label::kDeferred);
+ GotoIf(IsJSReceiverInstanceType(right_instance_type),
+ &if_right_receiver);
+
+ var_left.Bind(
+ CallBuiltin(Builtins::kNonNumberToNumeric, context, left));
+ var_right.Bind(CallBuiltin(Builtins::kToNumeric, context, right));
+ Goto(&loop);
- BIND(&if_rhsisreceiver);
+ BIND(&if_right_receiver);
{
- // Convert {rhs} to a primitive first passing Number hint.
Callable callable = CodeFactory::NonPrimitiveToPrimitive(
isolate(), ToPrimitiveHint::kNumber);
- var_rhs.Bind(CallStub(callable, context, rhs));
- Goto(&loop);
- }
-
- BIND(&if_rhsisnotreceiver);
- {
- // Convert both {lhs} and {rhs} to Numeric.
- var_lhs.Bind(
- CallBuiltin(Builtins::kNonNumberToNumeric, context, lhs));
- var_rhs.Bind(CallBuiltin(Builtins::kToNumeric, context, rhs));
+ var_right.Bind(CallStub(callable, context, right));
Goto(&loop);
}
}
}
- BIND(&if_lhsisother);
+ BIND(&if_left_other);
{
- // The {lhs} is neither a Numeric nor a String, and {rhs} is not
- // an Smi.
+ // {left} is neither a Numeric nor a String, and {right} is not a Smi.
if (var_type_feedback != nullptr) {
- // Collect NumberOrOddball feedback if {lhs} is an Oddball
- // and {rhs} is either a HeapNumber or Oddball. Otherwise collect
+ // Collect NumberOrOddball feedback if {left} is an Oddball
+ // and {right} is either a HeapNumber or Oddball. Otherwise collect
// Any feedback.
Label collect_any_feedback(this), collect_oddball_feedback(this),
collect_feedback_done(this);
- GotoIfNot(InstanceTypeEqual(lhs_instance_type, ODDBALL_TYPE),
+ GotoIfNot(InstanceTypeEqual(left_instance_type, ODDBALL_TYPE),
&collect_any_feedback);
- Node* rhs_instance_type = LoadMapInstanceType(rhs_map);
- GotoIf(InstanceTypeEqual(rhs_instance_type, HEAP_NUMBER_TYPE),
- &collect_oddball_feedback);
- Branch(InstanceTypeEqual(rhs_instance_type, ODDBALL_TYPE),
+ GotoIf(IsHeapNumberMap(right_map), &collect_oddball_feedback);
+ Node* right_instance_type = LoadMapInstanceType(right_map);
+ Branch(InstanceTypeEqual(right_instance_type, ODDBALL_TYPE),
&collect_oddball_feedback, &collect_any_feedback);
BIND(&collect_oddball_feedback);
{
- CombineFeedback(
- var_type_feedback,
- SmiConstant(CompareOperationFeedback::kNumberOrOddball));
+ CombineFeedback(var_type_feedback,
+ CompareOperationFeedback::kNumberOrOddball);
Goto(&collect_feedback_done);
}
BIND(&collect_any_feedback);
{
- var_type_feedback->Bind(
- SmiConstant(CompareOperationFeedback::kAny));
+ OverwriteFeedback(var_type_feedback,
+ CompareOperationFeedback::kAny);
Goto(&collect_feedback_done);
}
BIND(&collect_feedback_done);
}
- // If {lhs} is a receiver, we must call ToPrimitive(lhs, hint Number).
- // Otherwise we must call ToNumeric(lhs) and then ToNumeric(rhs).
+ // If {left} is a receiver, call ToPrimitive(left, hint Number).
+ // Otherwise call ToNumeric(left) and then ToNumeric(right).
STATIC_ASSERT(LAST_JS_RECEIVER_TYPE == LAST_TYPE);
- Label if_lhsisreceiver(this, Label::kDeferred),
- if_lhsisnotreceiver(this, Label::kDeferred);
- Branch(IsJSReceiverInstanceType(lhs_instance_type), &if_lhsisreceiver,
- &if_lhsisnotreceiver);
+ Label if_left_receiver(this, Label::kDeferred);
+ GotoIf(IsJSReceiverInstanceType(left_instance_type),
+ &if_left_receiver);
+
+ var_left.Bind(
+ CallBuiltin(Builtins::kNonNumberToNumeric, context, left));
+ var_right.Bind(CallBuiltin(Builtins::kToNumeric, context, right));
+ Goto(&loop);
- BIND(&if_lhsisreceiver);
+ BIND(&if_left_receiver);
{
Callable callable = CodeFactory::NonPrimitiveToPrimitive(
isolate(), ToPrimitiveHint::kNumber);
- var_lhs.Bind(CallStub(callable, context, lhs));
- Goto(&loop);
- }
-
- BIND(&if_lhsisnotreceiver);
- {
- var_lhs.Bind(
- CallBuiltin(Builtins::kNonNumberToNumeric, context, lhs));
- var_rhs.Bind(CallBuiltin(Builtins::kToNumeric, context, rhs));
+ var_left.Bind(CallStub(callable, context, left));
Goto(&loop);
}
}
@@ -8695,26 +8644,24 @@ Node* CodeStubAssembler::RelationalComparison(Operation op, Node* lhs,
}
}
- BIND(&do_fcmp);
+ BIND(&do_float_comparison);
{
- // Load the {lhs} and {rhs} floating point values.
- Node* lhs = var_fcmp_lhs.value();
- Node* rhs = var_fcmp_rhs.value();
-
- // Perform a fast floating point comparison.
switch (op) {
case Operation::kLessThan:
- Branch(Float64LessThan(lhs, rhs), &return_true, &return_false);
+ Branch(Float64LessThan(var_left_float, var_right_float), &return_true,
+ &return_false);
break;
case Operation::kLessThanOrEqual:
- Branch(Float64LessThanOrEqual(lhs, rhs), &return_true, &return_false);
+ Branch(Float64LessThanOrEqual(var_left_float, var_right_float),
+ &return_true, &return_false);
break;
case Operation::kGreaterThan:
- Branch(Float64GreaterThan(lhs, rhs), &return_true, &return_false);
+ Branch(Float64GreaterThan(var_left_float, var_right_float),
+ &return_true, &return_false);
break;
case Operation::kGreaterThanOrEqual:
- Branch(Float64GreaterThanOrEqual(lhs, rhs), &return_true,
- &return_false);
+ Branch(Float64GreaterThanOrEqual(var_left_float, var_right_float),
+ &return_true, &return_false);
break;
default:
UNREACHABLE();
@@ -8723,18 +8670,18 @@ Node* CodeStubAssembler::RelationalComparison(Operation op, Node* lhs,
BIND(&return_true);
{
- result.Bind(TrueConstant());
+ var_result = TrueConstant();
Goto(&end);
}
BIND(&return_false);
{
- result.Bind(FalseConstant());
+ var_result = FalseConstant();
Goto(&end);
}
BIND(&end);
- return result.value();
+ return var_result;
}
Node* CodeStubAssembler::CollectFeedbackForString(Node* instance_type) {
@@ -8764,10 +8711,11 @@ void CodeStubAssembler::GenerateEqual_Same(Node* value, Label* if_equal,
if (var_type_feedback != nullptr) {
Node* instance_type = LoadMapInstanceType(value_map);
- Label if_string(this), if_receiver(this), if_symbol(this),
+ Label if_string(this), if_receiver(this), if_symbol(this), if_bigint(this),
if_other(this, Label::kDeferred);
GotoIf(IsStringInstanceType(instance_type), &if_string);
GotoIf(IsJSReceiverInstanceType(instance_type), &if_receiver);
+ GotoIf(IsBigIntInstanceType(instance_type), &if_bigint);
Branch(IsSymbolInstanceType(instance_type), &if_symbol, &if_other);
BIND(&if_string);
@@ -8779,25 +8727,25 @@ void CodeStubAssembler::GenerateEqual_Same(Node* value, Label* if_equal,
BIND(&if_symbol);
{
- CombineFeedback(var_type_feedback,
- SmiConstant(CompareOperationFeedback::kSymbol));
+ CombineFeedback(var_type_feedback, CompareOperationFeedback::kSymbol);
Goto(if_equal);
}
BIND(&if_receiver);
{
- CombineFeedback(var_type_feedback,
- SmiConstant(CompareOperationFeedback::kReceiver));
+ CombineFeedback(var_type_feedback, CompareOperationFeedback::kReceiver);
Goto(if_equal);
}
- // TODO(neis): Introduce BigInt CompareOperationFeedback and collect here
- // and elsewhere?
+ BIND(&if_bigint);
+ {
+ CombineFeedback(var_type_feedback, CompareOperationFeedback::kBigInt);
+ Goto(if_equal);
+ }
BIND(&if_other);
{
- CombineFeedback(var_type_feedback,
- SmiConstant(CompareOperationFeedback::kAny));
+ CombineFeedback(var_type_feedback, CompareOperationFeedback::kAny);
Goto(if_equal);
}
} else {
@@ -8806,20 +8754,14 @@ void CodeStubAssembler::GenerateEqual_Same(Node* value, Label* if_equal,
BIND(&if_heapnumber);
{
- if (var_type_feedback != nullptr) {
- CombineFeedback(var_type_feedback,
- SmiConstant(CompareOperationFeedback::kNumber));
- }
+ CombineFeedback(var_type_feedback, CompareOperationFeedback::kNumber);
Node* number_value = LoadHeapNumberValue(value);
BranchIfFloat64IsNaN(number_value, if_notequal, if_equal);
}
BIND(&if_smi);
{
- if (var_type_feedback != nullptr) {
- CombineFeedback(var_type_feedback,
- SmiConstant(CompareOperationFeedback::kSignedSmall));
- }
+ CombineFeedback(var_type_feedback, CompareOperationFeedback::kSignedSmall);
Goto(if_equal);
}
}
@@ -8847,10 +8789,10 @@ Node* CodeStubAssembler::Equal(Node* left, Node* right, Node* context,
VARIABLE(var_right, MachineRepresentation::kTagged, right);
VariableList loop_variable_list({&var_left, &var_right}, zone());
if (var_type_feedback != nullptr) {
- // Initialize the type feedback to None. The current feedback is combined
- // with the previous feedback.
- var_type_feedback->Bind(SmiConstant(CompareOperationFeedback::kNone));
- loop_variable_list.Add(var_type_feedback, zone());
+ // Initialize the type feedback to None. The current feedback will be
+ // combined with the previous feedback.
+ OverwriteFeedback(var_type_feedback, CompareOperationFeedback::kNone);
+ loop_variable_list.push_back(var_type_feedback);
}
Label loop(this, loop_variable_list);
Goto(&loop);
@@ -8880,10 +8822,8 @@ Node* CodeStubAssembler::Equal(Node* left, Node* right, Node* context,
{
// We have already checked for {left} and {right} being the same value,
// so when we get here they must be different Smis.
- if (var_type_feedback != nullptr) {
- CombineFeedback(var_type_feedback,
- SmiConstant(CompareOperationFeedback::kSignedSmall));
- }
+ CombineFeedback(var_type_feedback,
+ CompareOperationFeedback::kSignedSmall);
Goto(&if_notequal);
}
@@ -8908,10 +8848,7 @@ Node* CodeStubAssembler::Equal(Node* left, Node* right, Node* context,
{
var_left_float = SmiToFloat64(left);
var_right_float = LoadHeapNumberValue(right);
- if (var_type_feedback != nullptr) {
- CombineFeedback(var_type_feedback,
- SmiConstant(CompareOperationFeedback::kNumber));
- }
+ CombineFeedback(var_type_feedback, CompareOperationFeedback::kNumber);
Goto(&do_float_comparison);
}
@@ -8961,11 +8898,9 @@ Node* CodeStubAssembler::Equal(Node* left, Node* right, Node* context,
{
GotoIfNot(IsStringInstanceType(right_type), &use_symmetry);
result.Bind(CallBuiltin(Builtins::kStringEqual, context, left, right));
- if (var_type_feedback != nullptr) {
- CombineFeedback(var_type_feedback,
- SmiOr(CollectFeedbackForString(left_type),
- CollectFeedbackForString(right_type)));
- }
+ CombineFeedback(var_type_feedback,
+ SmiOr(CollectFeedbackForString(left_type),
+ CollectFeedbackForString(right_type)));
Goto(&end);
}
@@ -8976,10 +8911,7 @@ Node* CodeStubAssembler::Equal(Node* left, Node* right, Node* context,
var_left_float = LoadHeapNumberValue(left);
var_right_float = LoadHeapNumberValue(right);
- if (var_type_feedback != nullptr) {
- CombineFeedback(var_type_feedback,
- SmiConstant(CompareOperationFeedback::kNumber));
- }
+ CombineFeedback(var_type_feedback, CompareOperationFeedback::kNumber);
Goto(&do_float_comparison);
BIND(&if_right_not_number);
@@ -9005,10 +8937,6 @@ Node* CodeStubAssembler::Equal(Node* left, Node* right, Node* context,
BIND(&if_left_bigint);
{
- if (var_type_feedback != nullptr) {
- var_type_feedback->Bind(SmiConstant(CompareOperationFeedback::kAny));
- }
-
Label if_right_heapnumber(this), if_right_bigint(this),
if_right_string(this), if_right_boolean(this);
GotoIf(IsHeapNumberMap(right_map), &if_right_heapnumber);
@@ -9020,6 +8948,10 @@ Node* CodeStubAssembler::Equal(Node* left, Node* right, Node* context,
BIND(&if_right_heapnumber);
{
+ if (var_type_feedback != nullptr) {
+ var_type_feedback->Bind(
+ SmiConstant(CompareOperationFeedback::kAny));
+ }
result.Bind(CallRuntime(Runtime::kBigIntEqualToNumber,
NoContextConstant(), left, right));
Goto(&end);
@@ -9027,6 +8959,7 @@ Node* CodeStubAssembler::Equal(Node* left, Node* right, Node* context,
BIND(&if_right_bigint);
{
+ CombineFeedback(var_type_feedback, CompareOperationFeedback::kBigInt);
result.Bind(CallRuntime(Runtime::kBigIntEqualToBigInt,
NoContextConstant(), left, right));
Goto(&end);
@@ -9034,6 +8967,10 @@ Node* CodeStubAssembler::Equal(Node* left, Node* right, Node* context,
BIND(&if_right_string);
{
+ if (var_type_feedback != nullptr) {
+ var_type_feedback->Bind(
+ SmiConstant(CompareOperationFeedback::kAny));
+ }
result.Bind(CallRuntime(Runtime::kBigIntEqualToString,
NoContextConstant(), left, right));
Goto(&end);
@@ -9041,6 +8978,10 @@ Node* CodeStubAssembler::Equal(Node* left, Node* right, Node* context,
BIND(&if_right_boolean);
{
+ if (var_type_feedback != nullptr) {
+ var_type_feedback->Bind(
+ SmiConstant(CompareOperationFeedback::kAny));
+ }
var_right.Bind(LoadObjectField(right, Oddball::kToNumberOffset));
Goto(&loop);
}
@@ -9083,7 +9024,7 @@ Node* CodeStubAssembler::Equal(Node* left, Node* right, Node* context,
BIND(&if_right_symbol);
{
CombineFeedback(var_type_feedback,
- SmiConstant(CompareOperationFeedback::kSymbol));
+ CompareOperationFeedback::kSymbol);
Goto(&if_notequal);
}
} else {
@@ -9109,10 +9050,7 @@ Node* CodeStubAssembler::Equal(Node* left, Node* right, Node* context,
GotoIfNot(IsJSReceiverInstanceType(right_type), &if_right_not_receiver);
// {left} and {right} are different JSReceiver references.
- if (var_type_feedback != nullptr) {
- CombineFeedback(var_type_feedback,
- SmiConstant(CompareOperationFeedback::kReceiver));
- }
+ CombineFeedback(var_type_feedback, CompareOperationFeedback::kReceiver);
Goto(&if_notequal);
BIND(&if_right_not_receiver);
@@ -9380,10 +9318,8 @@ Node* CodeStubAssembler::StrictEqual(Node* lhs, Node* rhs,
BIND(&if_rhsisbigint);
{
if (var_type_feedback != nullptr) {
- CSA_ASSERT(
- this,
- WordEqual(var_type_feedback->value(),
- SmiConstant(CompareOperationFeedback::kAny)));
+ var_type_feedback->Bind(
+ SmiConstant(CompareOperationFeedback::kBigInt));
}
result.Bind(CallRuntime(Runtime::kBigIntEqualToBigInt,
NoContextConstant(), lhs, rhs));
@@ -9607,8 +9543,10 @@ void CodeStubAssembler::BranchIfSameValue(Node* lhs, Node* rhs, Label* if_true,
}
}
-Node* CodeStubAssembler::HasProperty(Node* object, Node* key, Node* context,
- HasPropertyLookupMode mode) {
+TNode<Oddball> CodeStubAssembler::HasProperty(SloppyTNode<HeapObject> object,
+ SloppyTNode<Name> key,
+ SloppyTNode<Context> context,
+ HasPropertyLookupMode mode) {
Label call_runtime(this, Label::kDeferred), return_true(this),
return_false(this), end(this), if_proxy(this, Label::kDeferred);
@@ -9633,16 +9571,16 @@ Node* CodeStubAssembler::HasProperty(Node* object, Node* key, Node* context,
lookup_element_in_holder, &return_false,
&call_runtime, &if_proxy);
- VARIABLE(result, MachineRepresentation::kTagged);
+ TVARIABLE(Oddball, result);
BIND(&if_proxy);
{
- Node* name = ToName(context, key);
+ TNode<Name> name = CAST(ToName(context, key));
switch (mode) {
case kHasProperty:
GotoIf(IsPrivateSymbol(name), &return_false);
- result.Bind(
+ result = CAST(
CallBuiltin(Builtins::kProxyHasProperty, context, object, name));
Goto(&end);
break;
@@ -9654,13 +9592,13 @@ Node* CodeStubAssembler::HasProperty(Node* object, Node* key, Node* context,
BIND(&return_true);
{
- result.Bind(TrueConstant());
+ result = TrueConstant();
Goto(&end);
}
BIND(&return_false);
{
- result.Bind(FalseConstant());
+ result = FalseConstant();
Goto(&end);
}
@@ -9676,13 +9614,14 @@ Node* CodeStubAssembler::HasProperty(Node* object, Node* key, Node* context,
break;
}
- result.Bind(
- CallRuntime(fallback_runtime_function_id, context, object, key));
+ result =
+ CAST(CallRuntime(fallback_runtime_function_id, context, object, key));
Goto(&end);
}
BIND(&end);
- return result.value();
+ CSA_ASSERT(this, IsBoolean(result));
+ return result;
}
Node* CodeStubAssembler::ClassOf(Node* value) {
@@ -9769,10 +9708,10 @@ Node* CodeStubAssembler::Typeof(Node* value) {
Node* callable_or_undetectable_mask = Word32And(
LoadMapBitField(map),
- Int32Constant(1 << Map::kIsCallable | 1 << Map::kIsUndetectable));
+ Int32Constant(Map::IsCallableBit::kMask | Map::IsUndetectableBit::kMask));
GotoIf(Word32Equal(callable_or_undetectable_mask,
- Int32Constant(1 << Map::kIsCallable)),
+ Int32Constant(Map::IsCallableBit::kMask)),
&return_function);
GotoIfNot(Word32Equal(callable_or_undetectable_mask, Int32Constant(0)),
@@ -10139,17 +10078,17 @@ Node* CodeStubAssembler::BitwiseOp(Node* left32, Node* right32,
return ChangeInt32ToTagged(Signed(Word32Xor(left32, right32)));
case Operation::kShiftLeft:
if (!Word32ShiftIsSafe()) {
- right32 = Word32And(right32, Int32Constant(0x1f));
+ right32 = Word32And(right32, Int32Constant(0x1F));
}
return ChangeInt32ToTagged(Signed(Word32Shl(left32, right32)));
case Operation::kShiftRight:
if (!Word32ShiftIsSafe()) {
- right32 = Word32And(right32, Int32Constant(0x1f));
+ right32 = Word32And(right32, Int32Constant(0x1F));
}
return ChangeInt32ToTagged(Signed(Word32Sar(left32, right32)));
case Operation::kShiftRightLogical:
if (!Word32ShiftIsSafe()) {
- right32 = Word32And(right32, Int32Constant(0x1f));
+ right32 = Word32And(right32, Int32Constant(0x1F));
}
return ChangeUint32ToTagged(Unsigned(Word32Shr(left32, right32)));
default:
@@ -10426,7 +10365,7 @@ Node* CodeStubAssembler::IsDetachedBuffer(Node* buffer) {
}
CodeStubArguments::CodeStubArguments(
- CodeStubAssembler* assembler, SloppyTNode<IntPtrT> argc, Node* fp,
+ CodeStubAssembler* assembler, Node* argc, Node* fp,
CodeStubAssembler::ParameterMode param_mode, ReceiverMode receiver_mode)
: assembler_(assembler),
argc_mode_(param_mode),
@@ -10463,7 +10402,7 @@ TNode<Object> CodeStubArguments::AtIndex(
Node* index, CodeStubAssembler::ParameterMode mode) const {
DCHECK_EQ(argc_mode_, mode);
CSA_ASSERT(assembler_,
- assembler_->UintPtrOrSmiLessThan(index, GetLength(), mode));
+ assembler_->UintPtrOrSmiLessThan(index, GetLength(mode), mode));
return assembler_->UncheckedCast<Object>(
assembler_->Load(MachineType::AnyTagged(), AtIndexPtr(index, mode)));
}
@@ -10529,7 +10468,9 @@ void CodeStubArguments::PopAndReturn(Node* value) {
} else {
pop_count = argc_;
}
- assembler_->PopAndReturn(pop_count, value);
+
+ assembler_->PopAndReturn(assembler_->ParameterToWord(pop_count, argc_mode_),
+ value);
}
Node* CodeStubAssembler::IsFastElementsKind(Node* elements_kind) {
@@ -10586,6 +10527,7 @@ Node* CodeStubAssembler::AllocateFunctionWithMapAndContext(Node* map,
CSA_ASSERT(this, Word32BinaryNot(IsConstructorMap(map)));
CSA_ASSERT(this, Word32BinaryNot(IsFunctionWithPrototypeSlotMap(map)));
Node* const fun = Allocate(JSFunction::kSizeWithoutPrototype);
+ STATIC_ASSERT(JSFunction::kSizeWithoutPrototype == 7 * kPointerSize);
StoreMapNoWriteBarrier(fun, map);
StoreObjectFieldRoot(fun, JSObject::kPropertiesOrHashOffset,
Heap::kEmptyFixedArrayRootIndex);
@@ -10752,5 +10694,23 @@ void CodeStubAssembler::PerformStackCheck(Node* context) {
BIND(&ok);
}
+void CodeStubAssembler::InitializeFunctionContext(Node* native_context,
+ Node* context, int slots) {
+ DCHECK_GE(slots, Context::MIN_CONTEXT_SLOTS);
+ StoreMapNoWriteBarrier(context, Heap::kFunctionContextMapRootIndex);
+ StoreObjectFieldNoWriteBarrier(context, FixedArray::kLengthOffset,
+ SmiConstant(slots));
+
+ Node* const empty_fn =
+ LoadContextElement(native_context, Context::CLOSURE_INDEX);
+ StoreContextElementNoWriteBarrier(context, Context::CLOSURE_INDEX, empty_fn);
+ StoreContextElementNoWriteBarrier(context, Context::PREVIOUS_INDEX,
+ UndefinedConstant());
+ StoreContextElementNoWriteBarrier(context, Context::EXTENSION_INDEX,
+ TheHoleConstant());
+ StoreContextElementNoWriteBarrier(context, Context::NATIVE_CONTEXT_INDEX,
+ native_context);
+}
+
} // namespace internal
} // namespace v8