diff options
author | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2020-10-12 14:27:29 +0200 |
---|---|---|
committer | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2020-10-13 09:35:20 +0000 |
commit | c30a6232df03e1efbd9f3b226777b07e087a1122 (patch) | |
tree | e992f45784689f373bcc38d1b79a239ebe17ee23 /chromium/v8/src/ic | |
parent | 7b5b123ac58f58ffde0f4f6e488bcd09aa4decd3 (diff) | |
download | qtwebengine-chromium-85-based.tar.gz |
BASELINE: Update Chromium to 85.0.4183.14085-based
Change-Id: Iaa42f4680837c57725b1344f108c0196741f6057
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
Diffstat (limited to 'chromium/v8/src/ic')
-rw-r--r-- | chromium/v8/src/ic/accessor-assembler.cc | 34 | ||||
-rw-r--r-- | chromium/v8/src/ic/binary-op-assembler.cc | 13 | ||||
-rw-r--r-- | chromium/v8/src/ic/binary-op-assembler.h | 66 | ||||
-rw-r--r-- | chromium/v8/src/ic/ic.cc | 28 | ||||
-rw-r--r-- | chromium/v8/src/ic/unary-op-assembler.cc | 283 | ||||
-rw-r--r-- | chromium/v8/src/ic/unary-op-assembler.h | 45 |
6 files changed, 446 insertions, 23 deletions
diff --git a/chromium/v8/src/ic/accessor-assembler.cc b/chromium/v8/src/ic/accessor-assembler.cc index fb82a23c32f..18287ecc482 100644 --- a/chromium/v8/src/ic/accessor-assembler.cc +++ b/chromium/v8/src/ic/accessor-assembler.cc @@ -1334,12 +1334,13 @@ void AccessorAssembler::OverwriteExistingFastDataProperty( if (do_transitioning_store) { StoreMap(object, object_map); } else { - Label if_mutable(this); - GotoIfNot(IsPropertyDetailsConst(details), &if_mutable); + Label store_value(this); + GotoIfNot(IsPropertyDetailsConst(details), &store_value); TNode<Float64T> current_value = LoadObjectField<Float64T>(object, field_offset); - BranchIfSameNumberValue(current_value, double_value, &done, slow); - BIND(&if_mutable); + BranchIfSameNumberValue(current_value, double_value, &store_value, + slow); + BIND(&store_value); } StoreObjectFieldNoWriteBarrier(object, field_offset, double_value); } else { @@ -1351,11 +1352,12 @@ void AccessorAssembler::OverwriteExistingFastDataProperty( } else { TNode<HeapNumber> heap_number = CAST(LoadObjectField(object, field_offset)); - Label if_mutable(this); - GotoIfNot(IsPropertyDetailsConst(details), &if_mutable); + Label store_value(this); + GotoIfNot(IsPropertyDetailsConst(details), &store_value); TNode<Float64T> current_value = LoadHeapNumberValue(heap_number); - BranchIfSameNumberValue(current_value, double_value, &done, slow); - BIND(&if_mutable); + BranchIfSameNumberValue(current_value, double_value, &store_value, + slow); + BIND(&store_value); StoreHeapNumberValue(heap_number, double_value); } } @@ -1968,23 +1970,21 @@ TNode<PropertyArray> AccessorAssembler::ExtendPropertiesBackingStore( // Previous property deletion could have left behind unused backing store // capacity even for a map that think it doesn't have any unused fields. // Perform a bounds check to see if we actually have to grow the array. - GotoIf(UintPtrLessThan(index, ParameterToIntPtr(var_length.value(), mode)), + GotoIf(UintPtrLessThan(index, ParameterToIntPtr(var_length.value())), &done); TNode<BInt> delta = BIntConstant(JSObject::kFieldsAdded); - Node* new_capacity = IntPtrOrSmiAdd(var_length.value(), delta, mode); + TNode<BInt> new_capacity = IntPtrOrSmiAdd(var_length.value(), delta); // Grow properties array. DCHECK(kMaxNumberOfDescriptors + JSObject::kFieldsAdded < FixedArrayBase::GetMaxLengthForNewSpaceAllocation(PACKED_ELEMENTS)); // The size of a new properties backing store is guaranteed to be small // enough that the new backing store will be allocated in new space. - CSA_ASSERT(this, - UintPtrOrSmiLessThan( - new_capacity, - IntPtrOrSmiConstant( - kMaxNumberOfDescriptors + JSObject::kFieldsAdded, mode), - mode)); + CSA_ASSERT(this, UintPtrOrSmiLessThan( + new_capacity, + IntPtrOrSmiConstant<BInt>(kMaxNumberOfDescriptors + + JSObject::kFieldsAdded))); TNode<PropertyArray> new_properties = AllocatePropertyArray(new_capacity, mode); @@ -2002,7 +2002,7 @@ TNode<PropertyArray> AccessorAssembler::ExtendPropertiesBackingStore( // TODO(gsathya): Clean up the type conversions by creating smarter // helpers that do the correct op based on the mode. TNode<Int32T> new_capacity_int32 = - TruncateIntPtrToInt32(ParameterToIntPtr(new_capacity, mode)); + TruncateIntPtrToInt32(ParameterToIntPtr(new_capacity)); TNode<Int32T> new_length_and_hash_int32 = Word32Or(var_encoded_hash.value(), new_capacity_int32); StoreObjectField(new_properties, PropertyArray::kLengthAndHashOffset, diff --git a/chromium/v8/src/ic/binary-op-assembler.cc b/chromium/v8/src/ic/binary-op-assembler.cc index 25c2181ab2d..8cba7172a2e 100644 --- a/chromium/v8/src/ic/binary-op-assembler.cc +++ b/chromium/v8/src/ic/binary-op-assembler.cc @@ -69,6 +69,8 @@ TNode<Object> BinaryOpAssembler::Generate_AddWithFeedback( // Not overflowed. { var_type_feedback = SmiConstant(BinaryOperationFeedback::kSignedSmall); + UpdateFeedback(var_type_feedback.value(), maybe_feedback_vector, + slot_id); var_result = smi_result; Goto(&end); } @@ -116,6 +118,7 @@ TNode<Object> BinaryOpAssembler::Generate_AddWithFeedback( BIND(&do_fadd); { var_type_feedback = SmiConstant(BinaryOperationFeedback::kNumber); + UpdateFeedback(var_type_feedback.value(), maybe_feedback_vector, slot_id); TNode<Float64T> value = Float64Add(var_fadd_lhs.value(), var_fadd_rhs.value()); TNode<HeapNumber> result = AllocateHeapNumberWithValue(value); @@ -166,6 +169,8 @@ TNode<Object> BinaryOpAssembler::Generate_AddWithFeedback( &call_with_any_feedback); var_type_feedback = SmiConstant(BinaryOperationFeedback::kString); + UpdateFeedback(var_type_feedback.value(), maybe_feedback_vector, + slot_id); var_result = CallBuiltin(Builtins::kStringAdd_CheckNone, context, lhs, rhs); @@ -194,6 +199,7 @@ TNode<Object> BinaryOpAssembler::Generate_AddWithFeedback( GotoIf(TaggedIsSmi(var_result.value()), &bigint_too_big); var_type_feedback = SmiConstant(BinaryOperationFeedback::kBigInt); + UpdateFeedback(var_type_feedback.value(), maybe_feedback_vector, slot_id); Goto(&end); BIND(&bigint_too_big); @@ -219,12 +225,12 @@ TNode<Object> BinaryOpAssembler::Generate_AddWithFeedback( BIND(&call_add_stub); { + UpdateFeedback(var_type_feedback.value(), maybe_feedback_vector, slot_id); var_result = CallBuiltin(Builtins::kAdd, context, lhs, rhs); Goto(&end); } BIND(&end); - UpdateFeedback(var_type_feedback.value(), maybe_feedback_vector, slot_id); return var_result.value(); } @@ -279,6 +285,7 @@ TNode<Object> BinaryOpAssembler::Generate_BinaryOperationWithFeedback( { Comment("perform smi operation"); var_result = smiOperation(lhs_smi, CAST(rhs), &var_type_feedback); + UpdateFeedback(var_type_feedback.value(), maybe_feedback_vector, slot_id); Goto(&end); } } @@ -321,6 +328,7 @@ TNode<Object> BinaryOpAssembler::Generate_BinaryOperationWithFeedback( BIND(&do_float_operation); { var_type_feedback = SmiConstant(BinaryOperationFeedback::kNumber); + UpdateFeedback(var_type_feedback.value(), maybe_feedback_vector, slot_id); TNode<Float64T> lhs_value = var_float_lhs.value(); TNode<Float64T> rhs_value = var_float_rhs.value(); TNode<Float64T> value = floatOperation(lhs_value, rhs_value); @@ -384,6 +392,7 @@ TNode<Object> BinaryOpAssembler::Generate_BinaryOperationWithFeedback( BIND(&if_both_bigint); { var_type_feedback = SmiConstant(BinaryOperationFeedback::kBigInt); + UpdateFeedback(var_type_feedback.value(), maybe_feedback_vector, slot_id); if (op == Operation::kSubtract) { Label bigint_too_big(this); var_result = @@ -415,6 +424,7 @@ TNode<Object> BinaryOpAssembler::Generate_BinaryOperationWithFeedback( BIND(&call_stub); { + UpdateFeedback(var_type_feedback.value(), maybe_feedback_vector, slot_id); TNode<Object> result; switch (op) { case Operation::kSubtract: @@ -437,7 +447,6 @@ TNode<Object> BinaryOpAssembler::Generate_BinaryOperationWithFeedback( } BIND(&end); - UpdateFeedback(var_type_feedback.value(), maybe_feedback_vector, slot_id); return var_result.value(); } diff --git a/chromium/v8/src/ic/binary-op-assembler.h b/chromium/v8/src/ic/binary-op-assembler.h index 79b8cd221b9..4bd0d516089 100644 --- a/chromium/v8/src/ic/binary-op-assembler.h +++ b/chromium/v8/src/ic/binary-op-assembler.h @@ -50,6 +50,72 @@ class BinaryOpAssembler : public CodeStubAssembler { TNode<UintPtrT> slot, TNode<HeapObject> maybe_feedback_vector, bool rhs_known_smi); + TNode<Object> Generate_BitwiseOrWithFeedback( + TNode<Context> context, TNode<Object> left, TNode<Object> right, + TNode<UintPtrT> slot, TNode<HeapObject> maybe_feedback_vector, + bool /* unused */) { + TVARIABLE(Smi, feedback); + TNode<Object> result = Generate_BitwiseBinaryOpWithFeedback( + Operation::kBitwiseOr, left, right, context, &feedback); + UpdateFeedback(feedback.value(), maybe_feedback_vector, slot); + return result; + } + + TNode<Object> Generate_BitwiseXorWithFeedback( + TNode<Context> context, TNode<Object> left, TNode<Object> right, + TNode<UintPtrT> slot, TNode<HeapObject> maybe_feedback_vector, + bool /* unused */) { + TVARIABLE(Smi, feedback); + TNode<Object> result = Generate_BitwiseBinaryOpWithFeedback( + Operation::kBitwiseXor, left, right, context, &feedback); + UpdateFeedback(feedback.value(), maybe_feedback_vector, slot); + return result; + } + + TNode<Object> Generate_BitwiseAndWithFeedback( + TNode<Context> context, TNode<Object> left, TNode<Object> right, + TNode<UintPtrT> slot, TNode<HeapObject> maybe_feedback_vector, + bool /* unused */) { + TVARIABLE(Smi, feedback); + TNode<Object> result = Generate_BitwiseBinaryOpWithFeedback( + Operation::kBitwiseAnd, left, right, context, &feedback); + UpdateFeedback(feedback.value(), maybe_feedback_vector, slot); + return result; + } + + TNode<Object> Generate_ShiftLeftWithFeedback( + TNode<Context> context, TNode<Object> left, TNode<Object> right, + TNode<UintPtrT> slot, TNode<HeapObject> maybe_feedback_vector, + bool /* unused */) { + TVARIABLE(Smi, feedback); + TNode<Object> result = Generate_BitwiseBinaryOpWithFeedback( + Operation::kShiftLeft, left, right, context, &feedback); + UpdateFeedback(feedback.value(), maybe_feedback_vector, slot); + return result; + } + + TNode<Object> Generate_ShiftRightWithFeedback( + TNode<Context> context, TNode<Object> left, TNode<Object> right, + TNode<UintPtrT> slot, TNode<HeapObject> maybe_feedback_vector, + bool /* unused */) { + TVARIABLE(Smi, feedback); + TNode<Object> result = Generate_BitwiseBinaryOpWithFeedback( + Operation::kShiftRight, left, right, context, &feedback); + UpdateFeedback(feedback.value(), maybe_feedback_vector, slot); + return result; + } + + TNode<Object> Generate_ShiftRightLogicalWithFeedback( + TNode<Context> context, TNode<Object> left, TNode<Object> right, + TNode<UintPtrT> slot, TNode<HeapObject> maybe_feedback_vector, + bool /* unused */) { + TVARIABLE(Smi, feedback); + TNode<Object> result = Generate_BitwiseBinaryOpWithFeedback( + Operation::kShiftRightLogical, left, right, context, &feedback); + UpdateFeedback(feedback.value(), maybe_feedback_vector, slot); + return result; + } + TNode<Object> Generate_BitwiseBinaryOpWithFeedback(Operation bitwise_op, TNode<Object> left, TNode<Object> right, diff --git a/chromium/v8/src/ic/ic.cc b/chromium/v8/src/ic/ic.cc index 452275d13f2..9251d772ddc 100644 --- a/chromium/v8/src/ic/ic.cc +++ b/chromium/v8/src/ic/ic.cc @@ -8,6 +8,7 @@ #include "src/api/api.h" #include "src/ast/ast.h" #include "src/base/bits.h" +#include "src/base/logging.h" #include "src/builtins/accessors.h" #include "src/codegen/code-factory.h" #include "src/execution/arguments-inl.h" @@ -947,7 +948,9 @@ Handle<Object> LoadIC::ComputeHandler(LookupIterator* lookup) { TRACE_HANDLER_STATS(isolate(), LoadIC_LoadNormalDH); if (receiver_is_holder) return smi_handler; TRACE_HANDLER_STATS(isolate(), LoadIC_LoadNormalFromPrototypeDH); - + } else if (lookup->IsElement(*holder)) { + TRACE_HANDLER_STATS(isolate(), LoadIC_SlowStub); + return LoadHandler::LoadSlow(isolate()); } else { DCHECK_EQ(kField, lookup->property_details().location()); FieldIndex field = lookup->GetFieldIndex(); @@ -1769,6 +1772,12 @@ MaybeObjectHandle StoreIC::ComputeHandler(LookupIterator* lookup) { return MaybeObjectHandle(StoreHandler::StoreNormal(isolate())); } + // -------------- Elements (for TypedArrays) ------------- + if (lookup->IsElement(*holder)) { + TRACE_HANDLER_STATS(isolate(), StoreIC_SlowStub); + return MaybeObjectHandle(StoreHandler::StoreSlow(isolate())); + } + // -------------- Fields -------------- if (lookup->property_details().location() == kField) { TRACE_HANDLER_STATS(isolate(), StoreIC_StoreFieldDH); @@ -1856,6 +1865,12 @@ void KeyedStoreIC::UpdateStoreElement(Handle<Map> receiver_map, if (receiver_map.is_identical_to(previous_receiver_map) && new_receiver_map.is_identical_to(receiver_map) && old_store_mode == STANDARD_STORE && store_mode != STANDARD_STORE) { + if (receiver_map->IsJSArrayMap() && + JSArray::MayHaveReadOnlyLength(*receiver_map)) { + set_slow_stub_reason( + "can't generalize store mode (potentially read-only length)"); + return; + } // A "normal" IC that handles stores can switch to a version that can // grow at the end of the array, handle OOB accesses or copy COW arrays // and still stay MONOMORPHIC. @@ -1900,13 +1915,18 @@ void KeyedStoreIC::UpdateStoreElement(Handle<Map> receiver_map, } // If the store mode isn't the standard mode, make sure that all polymorphic - // receivers are either external arrays, or all "normal" arrays. Otherwise, - // use the megamorphic stub. + // receivers are either external arrays, or all "normal" arrays with writable + // length. Otherwise, use the megamorphic stub. if (store_mode != STANDARD_STORE) { size_t external_arrays = 0; for (MapAndHandler map_and_handler : target_maps_and_handlers) { Handle<Map> map = map_and_handler.first; - if (map->has_typed_array_elements()) { + if (map->IsJSArrayMap() && JSArray::MayHaveReadOnlyLength(*map)) { + set_slow_stub_reason( + "unsupported combination of arrays (potentially read-only length)"); + return; + + } else if (map->has_typed_array_elements()) { DCHECK(!IsStoreInArrayLiteralICKind(kind())); external_arrays++; } diff --git a/chromium/v8/src/ic/unary-op-assembler.cc b/chromium/v8/src/ic/unary-op-assembler.cc new file mode 100644 index 00000000000..6580601a1f4 --- /dev/null +++ b/chromium/v8/src/ic/unary-op-assembler.cc @@ -0,0 +1,283 @@ +// Copyright 2020 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "src/ic/unary-op-assembler.h" + +#include "src/common/globals.h" + +namespace v8 { +namespace internal { + +namespace { + +class UnaryOpAssemblerImpl final : public CodeStubAssembler { + public: + explicit UnaryOpAssemblerImpl(compiler::CodeAssemblerState* state) + : CodeStubAssembler(state) {} + + TNode<Object> BitwiseNot(TNode<Context> context, TNode<Object> value, + TNode<UintPtrT> slot, + TNode<HeapObject> maybe_feedback_vector) { + // TODO(jgruber): Make this implementation more consistent with other unary + // ops (i.e. have them all use UnaryOpWithFeedback or some other common + // mechanism). + TVARIABLE(Word32T, var_word32); + TVARIABLE(Smi, var_feedback); + TVARIABLE(BigInt, var_bigint); + TVARIABLE(Object, var_result); + Label if_number(this), if_bigint(this, Label::kDeferred), out(this); + TaggedToWord32OrBigIntWithFeedback(context, value, &if_number, &var_word32, + &if_bigint, &var_bigint, &var_feedback); + + // Number case. + BIND(&if_number); + var_result = + ChangeInt32ToTagged(Signed(Word32BitwiseNot(var_word32.value()))); + TNode<Smi> result_type = SelectSmiConstant( + TaggedIsSmi(var_result.value()), BinaryOperationFeedback::kSignedSmall, + BinaryOperationFeedback::kNumber); + UpdateFeedback(SmiOr(result_type, var_feedback.value()), + maybe_feedback_vector, slot); + Goto(&out); + + // BigInt case. + BIND(&if_bigint); + UpdateFeedback(SmiConstant(BinaryOperationFeedback::kBigInt), + maybe_feedback_vector, slot); + var_result = + CallRuntime(Runtime::kBigIntUnaryOp, context, var_bigint.value(), + SmiConstant(Operation::kBitwiseNot)); + Goto(&out); + + BIND(&out); + return var_result.value(); + } + + TNode<Object> Decrement(TNode<Context> context, TNode<Object> value, + TNode<UintPtrT> slot, + TNode<HeapObject> maybe_feedback_vector) { + return IncrementOrDecrement<Operation::kDecrement>(context, value, slot, + maybe_feedback_vector); + } + + TNode<Object> Increment(TNode<Context> context, TNode<Object> value, + TNode<UintPtrT> slot, + TNode<HeapObject> maybe_feedback_vector) { + return IncrementOrDecrement<Operation::kIncrement>(context, value, slot, + maybe_feedback_vector); + } + + TNode<Object> Negate(TNode<Context> context, TNode<Object> value, + TNode<UintPtrT> slot, + TNode<HeapObject> maybe_feedback_vector) { + SmiOperation smi_op = [=](TNode<Smi> smi_value, + TVariable<Smi>* var_feedback, Label* do_float_op, + TVariable<Float64T>* var_float) { + TVARIABLE(Number, var_result); + Label if_zero(this), if_min_smi(this), end(this); + // Return -0 if operand is 0. + GotoIf(SmiEqual(smi_value, SmiConstant(0)), &if_zero); + + // Special-case the minimum Smi to avoid overflow. + GotoIf(SmiEqual(smi_value, SmiConstant(Smi::kMinValue)), &if_min_smi); + + // Else simply subtract operand from 0. + CombineFeedback(var_feedback, BinaryOperationFeedback::kSignedSmall); + var_result = SmiSub(SmiConstant(0), smi_value); + Goto(&end); + + BIND(&if_zero); + CombineFeedback(var_feedback, BinaryOperationFeedback::kNumber); + var_result = MinusZeroConstant(); + Goto(&end); + + BIND(&if_min_smi); + *var_float = SmiToFloat64(smi_value); + Goto(do_float_op); + + BIND(&end); + return var_result.value(); + }; + FloatOperation float_op = [=](TNode<Float64T> float_value) { + return Float64Neg(float_value); + }; + BigIntOperation bigint_op = [=](TNode<Context> context, + TNode<HeapObject> bigint_value) { + return CAST(CallRuntime(Runtime::kBigIntUnaryOp, context, bigint_value, + SmiConstant(Operation::kNegate))); + }; + return UnaryOpWithFeedback(context, value, slot, maybe_feedback_vector, + smi_op, float_op, bigint_op); + } + + private: + using SmiOperation = std::function<TNode<Number>( + TNode<Smi> /* smi_value */, TVariable<Smi>* /* var_feedback */, + Label* /* do_float_op */, TVariable<Float64T>* /* var_float */)>; + using FloatOperation = + std::function<TNode<Float64T>(TNode<Float64T> /* float_value */)>; + using BigIntOperation = std::function<TNode<HeapObject>( + TNode<Context> /* context */, TNode<HeapObject> /* bigint_value */)>; + + TNode<Object> UnaryOpWithFeedback(TNode<Context> context, TNode<Object> value, + TNode<UintPtrT> slot, + TNode<HeapObject> maybe_feedback_vector, + const SmiOperation& smi_op, + const FloatOperation& float_op, + const BigIntOperation& bigint_op) { + TVARIABLE(Object, var_value, value); + TVARIABLE(Object, var_result); + TVARIABLE(Float64T, var_float_value); + TVARIABLE(Smi, var_feedback, SmiConstant(BinaryOperationFeedback::kNone)); + Label start(this, {&var_value, &var_feedback}), end(this); + Label do_float_op(this, &var_float_value); + Goto(&start); + // We might have to try again after ToNumeric conversion. + BIND(&start); + { + Label if_smi(this), if_heapnumber(this), if_oddball(this); + Label if_bigint(this, Label::kDeferred); + Label if_other(this, Label::kDeferred); + TNode<Object> value = var_value.value(); + GotoIf(TaggedIsSmi(value), &if_smi); + + TNode<HeapObject> value_heap_object = CAST(value); + TNode<Map> map = LoadMap(value_heap_object); + GotoIf(IsHeapNumberMap(map), &if_heapnumber); + TNode<Uint16T> instance_type = LoadMapInstanceType(map); + GotoIf(IsBigIntInstanceType(instance_type), &if_bigint); + Branch(InstanceTypeEqual(instance_type, ODDBALL_TYPE), &if_oddball, + &if_other); + + BIND(&if_smi); + { + var_result = + smi_op(CAST(value), &var_feedback, &do_float_op, &var_float_value); + Goto(&end); + } + + BIND(&if_heapnumber); + { + var_float_value = LoadHeapNumberValue(value_heap_object); + Goto(&do_float_op); + } + + BIND(&if_bigint); + { + var_result = bigint_op(context, value_heap_object); + CombineFeedback(&var_feedback, BinaryOperationFeedback::kBigInt); + Goto(&end); + } + + BIND(&if_oddball); + { + // We do not require an Or with earlier feedback here because once we + // convert the value to a number, we cannot reach this path. We can + // only reach this path on the first pass when the feedback is kNone. + CSA_ASSERT(this, SmiEqual(var_feedback.value(), + SmiConstant(BinaryOperationFeedback::kNone))); + OverwriteFeedback(&var_feedback, + BinaryOperationFeedback::kNumberOrOddball); + var_value = + LoadObjectField(value_heap_object, Oddball::kToNumberOffset); + Goto(&start); + } + + BIND(&if_other); + { + // We do not require an Or with earlier feedback here because once we + // convert the value to a number, we cannot reach this path. We can + // only reach this path on the first pass when the feedback is kNone. + CSA_ASSERT(this, SmiEqual(var_feedback.value(), + SmiConstant(BinaryOperationFeedback::kNone))); + OverwriteFeedback(&var_feedback, BinaryOperationFeedback::kAny); + var_value = CallBuiltin(Builtins::kNonNumberToNumeric, context, + value_heap_object); + Goto(&start); + } + } + + BIND(&do_float_op); + { + CombineFeedback(&var_feedback, BinaryOperationFeedback::kNumber); + var_result = + AllocateHeapNumberWithValue(float_op(var_float_value.value())); + Goto(&end); + } + + BIND(&end); + UpdateFeedback(var_feedback.value(), maybe_feedback_vector, slot); + return var_result.value(); + } + + template <Operation kOperation> + TNode<Object> IncrementOrDecrement(TNode<Context> context, + TNode<Object> value, TNode<UintPtrT> slot, + TNode<HeapObject> maybe_feedback_vector) { + STATIC_ASSERT(kOperation == Operation::kIncrement || + kOperation == Operation::kDecrement); + static constexpr int kAddValue = + (kOperation == Operation::kIncrement) ? 1 : -1; + + SmiOperation smi_op = [=](TNode<Smi> smi_value, + TVariable<Smi>* var_feedback, Label* do_float_op, + TVariable<Float64T>* var_float) { + Label if_overflow(this), out(this); + TNode<Smi> result = + TrySmiAdd(smi_value, SmiConstant(kAddValue), &if_overflow); + CombineFeedback(var_feedback, BinaryOperationFeedback::kSignedSmall); + Goto(&out); + + BIND(&if_overflow); + *var_float = SmiToFloat64(smi_value); + Goto(do_float_op); + + BIND(&out); + return result; + }; + FloatOperation float_op = [=](TNode<Float64T> float_value) { + return Float64Add(float_value, Float64Constant(kAddValue)); + }; + BigIntOperation bigint_op = [=](TNode<Context> context, + TNode<HeapObject> bigint_value) { + return CAST(CallRuntime(Runtime::kBigIntUnaryOp, context, bigint_value, + SmiConstant(kOperation))); + }; + return UnaryOpWithFeedback(context, value, slot, maybe_feedback_vector, + smi_op, float_op, bigint_op); + } +}; + +} // namespace + +TNode<Object> UnaryOpAssembler::Generate_BitwiseNotWithFeedback( + TNode<Context> context, TNode<Object> value, TNode<UintPtrT> slot, + TNode<HeapObject> maybe_feedback_vector) { + UnaryOpAssemblerImpl a(state_); + return a.BitwiseNot(context, value, slot, maybe_feedback_vector); +} + +TNode<Object> UnaryOpAssembler::Generate_DecrementWithFeedback( + TNode<Context> context, TNode<Object> value, TNode<UintPtrT> slot, + TNode<HeapObject> maybe_feedback_vector) { + UnaryOpAssemblerImpl a(state_); + return a.Decrement(context, value, slot, maybe_feedback_vector); +} + +TNode<Object> UnaryOpAssembler::Generate_IncrementWithFeedback( + TNode<Context> context, TNode<Object> value, TNode<UintPtrT> slot, + TNode<HeapObject> maybe_feedback_vector) { + UnaryOpAssemblerImpl a(state_); + return a.Increment(context, value, slot, maybe_feedback_vector); +} + +TNode<Object> UnaryOpAssembler::Generate_NegateWithFeedback( + TNode<Context> context, TNode<Object> value, TNode<UintPtrT> slot, + TNode<HeapObject> maybe_feedback_vector) { + UnaryOpAssemblerImpl a(state_); + return a.Negate(context, value, slot, maybe_feedback_vector); +} + +} // namespace internal +} // namespace v8 diff --git a/chromium/v8/src/ic/unary-op-assembler.h b/chromium/v8/src/ic/unary-op-assembler.h new file mode 100644 index 00000000000..b22322ddf2a --- /dev/null +++ b/chromium/v8/src/ic/unary-op-assembler.h @@ -0,0 +1,45 @@ +// Copyright 2020 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef V8_IC_UNARY_OP_ASSEMBLER_H_ +#define V8_IC_UNARY_OP_ASSEMBLER_H_ + +#include "src/codegen/code-stub-assembler.h" + +namespace v8 { +namespace internal { + +namespace compiler { +class CodeAssemblerState; +} + +class UnaryOpAssembler final { + public: + explicit UnaryOpAssembler(compiler::CodeAssemblerState* state) + : state_(state) {} + + TNode<Object> Generate_BitwiseNotWithFeedback( + TNode<Context> context, TNode<Object> value, TNode<UintPtrT> slot, + TNode<HeapObject> maybe_feedback_vector); + + TNode<Object> Generate_DecrementWithFeedback( + TNode<Context> context, TNode<Object> value, TNode<UintPtrT> slot, + TNode<HeapObject> maybe_feedback_vector); + + TNode<Object> Generate_IncrementWithFeedback( + TNode<Context> context, TNode<Object> value, TNode<UintPtrT> slot, + TNode<HeapObject> maybe_feedback_vector); + + TNode<Object> Generate_NegateWithFeedback( + TNode<Context> context, TNode<Object> value, TNode<UintPtrT> slot, + TNode<HeapObject> maybe_feedback_vector); + + private: + compiler::CodeAssemblerState* const state_; +}; + +} // namespace internal +} // namespace v8 + +#endif // V8_IC_UNARY_OP_ASSEMBLER_H_ |