| Index: runtime/vm/intrinsifier_x64.cc
|
| diff --git a/runtime/vm/intrinsifier_x64.cc b/runtime/vm/intrinsifier_x64.cc
|
| index 3b97a1bf80b551b928e90e98d4abb018a306f006..1fb4a004edf39e48d9fb1d271c879d300d364822 100644
|
| --- a/runtime/vm/intrinsifier_x64.cc
|
| +++ b/runtime/vm/intrinsifier_x64.cc
|
| @@ -28,17 +28,14 @@ namespace dart {
|
|
|
| #define __ assembler->
|
|
|
| -
|
| intptr_t Intrinsifier::ParameterSlotFromSp() {
|
| return 0;
|
| }
|
|
|
| -
|
| static bool IsABIPreservedRegister(Register reg) {
|
| return ((1 << reg) & CallingConventions::kCalleeSaveCpuRegisters) != 0;
|
| }
|
|
|
| -
|
| void Intrinsifier::IntrinsicCallPrologue(Assembler* assembler) {
|
| ASSERT(IsABIPreservedRegister(CODE_REG));
|
| ASSERT(!IsABIPreservedRegister(ARGS_DESC_REG));
|
| @@ -50,13 +47,11 @@ void Intrinsifier::IntrinsicCallPrologue(Assembler* assembler) {
|
| assembler->movq(CALLEE_SAVED_TEMP, ARGS_DESC_REG);
|
| }
|
|
|
| -
|
| void Intrinsifier::IntrinsicCallEpilogue(Assembler* assembler) {
|
| assembler->Comment("IntrinsicCallEpilogue");
|
| assembler->movq(ARGS_DESC_REG, CALLEE_SAVED_TEMP);
|
| }
|
|
|
| -
|
| void Intrinsifier::ObjectArraySetIndexed(Assembler* assembler) {
|
| if (Isolate::Current()->type_checks()) {
|
| return;
|
| @@ -82,7 +77,6 @@ void Intrinsifier::ObjectArraySetIndexed(Assembler* assembler) {
|
| __ Bind(&fall_through);
|
| }
|
|
|
| -
|
| // Allocate a GrowableObjectArray using the backing array specified.
|
| // On stack: type argument (+2), data (+1), return-address (+0).
|
| void Intrinsifier::GrowableArray_Allocate(Assembler* assembler) {
|
| @@ -118,7 +112,6 @@ void Intrinsifier::GrowableArray_Allocate(Assembler* assembler) {
|
| __ Bind(&fall_through);
|
| }
|
|
|
| -
|
| // Add an element to growable array if it doesn't need to grow, otherwise
|
| // call into regular code.
|
| // On stack: growable array (+2), value (+1), return-address (+0).
|
| @@ -146,7 +139,6 @@ void Intrinsifier::GrowableArray_add(Assembler* assembler) {
|
| __ Bind(&fall_through);
|
| }
|
|
|
| -
|
| #define TYPED_ARRAY_ALLOCATION(type_name, cid, max_len, scale_factor) \
|
| Label fall_through; \
|
| const intptr_t kArrayLengthStackOffset = 1 * kWordSize; \
|
| @@ -242,7 +234,6 @@ void Intrinsifier::GrowableArray_add(Assembler* assembler) {
|
| __ ret(); \
|
| __ Bind(&fall_through);
|
|
|
| -
|
| static ScaleFactor GetScaleFactor(intptr_t size) {
|
| switch (size) {
|
| case 1:
|
| @@ -260,7 +251,6 @@ static ScaleFactor GetScaleFactor(intptr_t size) {
|
| return static_cast<ScaleFactor>(0);
|
| }
|
|
|
| -
|
| #define TYPED_DATA_ALLOCATOR(clazz) \
|
| void Intrinsifier::TypedData_##clazz##_factory(Assembler* assembler) { \
|
| intptr_t size = TypedData::ElementSizeInBytes(kTypedData##clazz##Cid); \
|
| @@ -271,7 +261,6 @@ static ScaleFactor GetScaleFactor(intptr_t size) {
|
| CLASS_LIST_TYPED_DATA(TYPED_DATA_ALLOCATOR)
|
| #undef TYPED_DATA_ALLOCATOR
|
|
|
| -
|
| // Tests if two top most arguments are smis, jumps to label not_smi if not.
|
| // Topmost argument is in RAX.
|
| static void TestBothArgumentsSmis(Assembler* assembler, Label* not_smi) {
|
| @@ -282,7 +271,6 @@ static void TestBothArgumentsSmis(Assembler* assembler, Label* not_smi) {
|
| __ j(NOT_ZERO, not_smi);
|
| }
|
|
|
| -
|
| void Intrinsifier::Integer_addFromInteger(Assembler* assembler) {
|
| Label fall_through;
|
| TestBothArgumentsSmis(assembler, &fall_through);
|
| @@ -294,12 +282,10 @@ void Intrinsifier::Integer_addFromInteger(Assembler* assembler) {
|
| __ Bind(&fall_through);
|
| }
|
|
|
| -
|
| void Intrinsifier::Integer_add(Assembler* assembler) {
|
| Integer_addFromInteger(assembler);
|
| }
|
|
|
| -
|
| void Intrinsifier::Integer_subFromInteger(Assembler* assembler) {
|
| Label fall_through;
|
| TestBothArgumentsSmis(assembler, &fall_through);
|
| @@ -311,7 +297,6 @@ void Intrinsifier::Integer_subFromInteger(Assembler* assembler) {
|
| __ Bind(&fall_through);
|
| }
|
|
|
| -
|
| void Intrinsifier::Integer_sub(Assembler* assembler) {
|
| Label fall_through;
|
| TestBothArgumentsSmis(assembler, &fall_through);
|
| @@ -325,7 +310,6 @@ void Intrinsifier::Integer_sub(Assembler* assembler) {
|
| __ Bind(&fall_through);
|
| }
|
|
|
| -
|
| void Intrinsifier::Integer_mulFromInteger(Assembler* assembler) {
|
| Label fall_through;
|
| TestBothArgumentsSmis(assembler, &fall_through);
|
| @@ -339,12 +323,10 @@ void Intrinsifier::Integer_mulFromInteger(Assembler* assembler) {
|
| __ Bind(&fall_through);
|
| }
|
|
|
| -
|
| void Intrinsifier::Integer_mul(Assembler* assembler) {
|
| Integer_mulFromInteger(assembler);
|
| }
|
|
|
| -
|
| // Optimizations:
|
| // - result is 0 if:
|
| // - left is 0
|
| @@ -408,7 +390,6 @@ static void EmitRemainderOperation(Assembler* assembler) {
|
| __ Bind(&done);
|
| }
|
|
|
| -
|
| // Implementation:
|
| // res = left % right;
|
| // if (res < 0) {
|
| @@ -451,7 +432,6 @@ void Intrinsifier::Integer_moduloFromInteger(Assembler* assembler) {
|
| __ Bind(&fall_through);
|
| }
|
|
|
| -
|
| void Intrinsifier::Integer_truncDivide(Assembler* assembler) {
|
| Label fall_through, not_32bit;
|
| TestBothArgumentsSmis(assembler, &fall_through);
|
| @@ -498,7 +478,6 @@ void Intrinsifier::Integer_truncDivide(Assembler* assembler) {
|
| __ Bind(&fall_through);
|
| }
|
|
|
| -
|
| void Intrinsifier::Integer_negate(Assembler* assembler) {
|
| Label fall_through;
|
| __ movq(RAX, Address(RSP, +1 * kWordSize));
|
| @@ -511,7 +490,6 @@ void Intrinsifier::Integer_negate(Assembler* assembler) {
|
| __ Bind(&fall_through);
|
| }
|
|
|
| -
|
| void Intrinsifier::Integer_bitAndFromInteger(Assembler* assembler) {
|
| Label fall_through;
|
| TestBothArgumentsSmis(assembler, &fall_through);
|
| @@ -522,12 +500,10 @@ void Intrinsifier::Integer_bitAndFromInteger(Assembler* assembler) {
|
| __ Bind(&fall_through);
|
| }
|
|
|
| -
|
| void Intrinsifier::Integer_bitAnd(Assembler* assembler) {
|
| Integer_bitAndFromInteger(assembler);
|
| }
|
|
|
| -
|
| void Intrinsifier::Integer_bitOrFromInteger(Assembler* assembler) {
|
| Label fall_through;
|
| TestBothArgumentsSmis(assembler, &fall_through);
|
| @@ -538,12 +514,10 @@ void Intrinsifier::Integer_bitOrFromInteger(Assembler* assembler) {
|
| __ Bind(&fall_through);
|
| }
|
|
|
| -
|
| void Intrinsifier::Integer_bitOr(Assembler* assembler) {
|
| Integer_bitOrFromInteger(assembler);
|
| }
|
|
|
| -
|
| void Intrinsifier::Integer_bitXorFromInteger(Assembler* assembler) {
|
| Label fall_through;
|
| TestBothArgumentsSmis(assembler, &fall_through);
|
| @@ -554,12 +528,10 @@ void Intrinsifier::Integer_bitXorFromInteger(Assembler* assembler) {
|
| __ Bind(&fall_through);
|
| }
|
|
|
| -
|
| void Intrinsifier::Integer_bitXor(Assembler* assembler) {
|
| Integer_bitXorFromInteger(assembler);
|
| }
|
|
|
| -
|
| void Intrinsifier::Integer_shl(Assembler* assembler) {
|
| ASSERT(kSmiTagShift == 1);
|
| ASSERT(kSmiTag == 0);
|
| @@ -591,7 +563,6 @@ void Intrinsifier::Integer_shl(Assembler* assembler) {
|
| __ Bind(&fall_through);
|
| }
|
|
|
| -
|
| static void CompareIntegers(Assembler* assembler, Condition true_condition) {
|
| Label fall_through, true_label;
|
| TestBothArgumentsSmis(assembler, &fall_through);
|
| @@ -606,32 +577,26 @@ static void CompareIntegers(Assembler* assembler, Condition true_condition) {
|
| __ Bind(&fall_through);
|
| }
|
|
|
| -
|
| void Intrinsifier::Integer_lessThan(Assembler* assembler) {
|
| CompareIntegers(assembler, LESS);
|
| }
|
|
|
| -
|
| void Intrinsifier::Integer_greaterThanFromInt(Assembler* assembler) {
|
| CompareIntegers(assembler, LESS);
|
| }
|
|
|
| -
|
| void Intrinsifier::Integer_greaterThan(Assembler* assembler) {
|
| CompareIntegers(assembler, GREATER);
|
| }
|
|
|
| -
|
| void Intrinsifier::Integer_lessEqualThan(Assembler* assembler) {
|
| CompareIntegers(assembler, LESS_EQUAL);
|
| }
|
|
|
| -
|
| void Intrinsifier::Integer_greaterEqualThan(Assembler* assembler) {
|
| CompareIntegers(assembler, GREATER_EQUAL);
|
| }
|
|
|
| -
|
| // This is called for Smi, Mint and Bigint receivers. The right argument
|
| // can be Smi, Mint, Bigint or double.
|
| void Intrinsifier::Integer_equalToInteger(Assembler* assembler) {
|
| @@ -686,12 +651,10 @@ void Intrinsifier::Integer_equalToInteger(Assembler* assembler) {
|
| __ Bind(&fall_through);
|
| }
|
|
|
| -
|
| void Intrinsifier::Integer_equal(Assembler* assembler) {
|
| Integer_equalToInteger(assembler);
|
| }
|
|
|
| -
|
| void Intrinsifier::Integer_sar(Assembler* assembler) {
|
| Label fall_through, shift_count_ok;
|
| TestBothArgumentsSmis(assembler, &fall_through);
|
| @@ -716,7 +679,6 @@ void Intrinsifier::Integer_sar(Assembler* assembler) {
|
| __ Bind(&fall_through);
|
| }
|
|
|
| -
|
| // Argument is Smi (receiver).
|
| void Intrinsifier::Smi_bitNegate(Assembler* assembler) {
|
| __ movq(RAX, Address(RSP, +1 * kWordSize)); // Index.
|
| @@ -725,7 +687,6 @@ void Intrinsifier::Smi_bitNegate(Assembler* assembler) {
|
| __ ret();
|
| }
|
|
|
| -
|
| void Intrinsifier::Smi_bitLength(Assembler* assembler) {
|
| ASSERT(kSmiTagShift == 1);
|
| __ movq(RAX, Address(RSP, +1 * kWordSize)); // Index.
|
| @@ -741,12 +702,10 @@ void Intrinsifier::Smi_bitLength(Assembler* assembler) {
|
| __ ret();
|
| }
|
|
|
| -
|
| void Intrinsifier::Smi_bitAndFromSmi(Assembler* assembler) {
|
| Integer_bitAndFromInteger(assembler);
|
| }
|
|
|
| -
|
| void Intrinsifier::Bigint_lsh(Assembler* assembler) {
|
| // static void _lsh(Uint32List x_digits, int x_used, int n,
|
| // Uint32List r_digits)
|
| @@ -771,8 +730,9 @@ void Intrinsifier::Bigint_lsh(Assembler* assembler) {
|
| Label loop;
|
| __ Bind(&loop);
|
| __ movq(RAX, RDX);
|
| - __ movq(RDX, FieldAddress(RDI, R8, TIMES_8, TypedData::data_offset() -
|
| - 2 * Bigint::kBytesPerDigit));
|
| + __ movq(RDX,
|
| + FieldAddress(RDI, R8, TIMES_8,
|
| + TypedData::data_offset() - 2 * Bigint::kBytesPerDigit));
|
| __ shldq(RAX, RDX, RCX);
|
| __ movq(Address(RBX, R8, TIMES_8, 0), RAX);
|
| __ decq(R8);
|
| @@ -784,7 +744,6 @@ void Intrinsifier::Bigint_lsh(Assembler* assembler) {
|
| __ ret();
|
| }
|
|
|
| -
|
| void Intrinsifier::Bigint_rsh(Assembler* assembler) {
|
| // static void _rsh(Uint32List x_digits, int x_used, int n,
|
| // Uint32List r_digits)
|
| @@ -821,7 +780,6 @@ void Intrinsifier::Bigint_rsh(Assembler* assembler) {
|
| __ ret();
|
| }
|
|
|
| -
|
| void Intrinsifier::Bigint_absAdd(Assembler* assembler) {
|
| // static void _absAdd(Uint32List digits, int used,
|
| // Uint32List a_digits, int a_used,
|
| @@ -877,7 +835,6 @@ void Intrinsifier::Bigint_absAdd(Assembler* assembler) {
|
| __ ret();
|
| }
|
|
|
| -
|
| void Intrinsifier::Bigint_absSub(Assembler* assembler) {
|
| // static void _absSub(Uint32List digits, int used,
|
| // Uint32List a_digits, int a_used,
|
| @@ -927,7 +884,6 @@ void Intrinsifier::Bigint_absSub(Assembler* assembler) {
|
| __ ret();
|
| }
|
|
|
| -
|
| void Intrinsifier::Bigint_mulAdd(Assembler* assembler) {
|
| // Pseudo code:
|
| // static int _mulAdd(Uint32List x_digits, int xi,
|
| @@ -1035,7 +991,6 @@ void Intrinsifier::Bigint_mulAdd(Assembler* assembler) {
|
| __ ret();
|
| }
|
|
|
| -
|
| void Intrinsifier::Bigint_sqrAdd(Assembler* assembler) {
|
| // Pseudo code:
|
| // static int _sqrAdd(Uint32List x_digits, int i,
|
| @@ -1155,7 +1110,6 @@ void Intrinsifier::Bigint_sqrAdd(Assembler* assembler) {
|
| __ ret();
|
| }
|
|
|
| -
|
| void Intrinsifier::Bigint_estQuotientDigit(Assembler* assembler) {
|
| // Pseudo code:
|
| // static int _estQuotientDigit(Uint32List args, Uint32List digits, int i) {
|
| @@ -1212,7 +1166,6 @@ void Intrinsifier::Bigint_estQuotientDigit(Assembler* assembler) {
|
| __ ret();
|
| }
|
|
|
| -
|
| void Intrinsifier::Montgomery_mulMod(Assembler* assembler) {
|
| // Pseudo code:
|
| // static int _mulMod(Uint32List args, Uint32List digits, int i) {
|
| @@ -1247,7 +1200,6 @@ void Intrinsifier::Montgomery_mulMod(Assembler* assembler) {
|
| __ ret();
|
| }
|
|
|
| -
|
| // Check if the last argument is a double, jump to label 'is_smi' if smi
|
| // (easy to convert to double), otherwise jump to label 'not_double_smi',
|
| // Returns the last argument in RAX.
|
| @@ -1262,7 +1214,6 @@ static void TestLastArgumentIsDouble(Assembler* assembler,
|
| // Fall through if double.
|
| }
|
|
|
| -
|
| // Both arguments on stack, left argument is a double, right argument is of
|
| // unknown type. Return true or false object in RAX. Any NaN argument
|
| // returns false. Any non-double argument causes control flow to fall through
|
| @@ -1292,32 +1243,26 @@ static void CompareDoubles(Assembler* assembler, Condition true_condition) {
|
| __ Bind(&fall_through);
|
| }
|
|
|
| -
|
| void Intrinsifier::Double_greaterThan(Assembler* assembler) {
|
| CompareDoubles(assembler, ABOVE);
|
| }
|
|
|
| -
|
| void Intrinsifier::Double_greaterEqualThan(Assembler* assembler) {
|
| CompareDoubles(assembler, ABOVE_EQUAL);
|
| }
|
|
|
| -
|
| void Intrinsifier::Double_lessThan(Assembler* assembler) {
|
| CompareDoubles(assembler, BELOW);
|
| }
|
|
|
| -
|
| void Intrinsifier::Double_equal(Assembler* assembler) {
|
| CompareDoubles(assembler, EQUAL);
|
| }
|
|
|
| -
|
| void Intrinsifier::Double_lessEqualThan(Assembler* assembler) {
|
| CompareDoubles(assembler, BELOW_EQUAL);
|
| }
|
|
|
| -
|
| // Expects left argument to be double (receiver). Right argument is unknown.
|
| // Both arguments are on stack.
|
| static void DoubleArithmeticOperations(Assembler* assembler, Token::Kind kind) {
|
| @@ -1358,27 +1303,22 @@ static void DoubleArithmeticOperations(Assembler* assembler, Token::Kind kind) {
|
| __ Bind(&fall_through);
|
| }
|
|
|
| -
|
| void Intrinsifier::Double_add(Assembler* assembler) {
|
| DoubleArithmeticOperations(assembler, Token::kADD);
|
| }
|
|
|
| -
|
| void Intrinsifier::Double_mul(Assembler* assembler) {
|
| DoubleArithmeticOperations(assembler, Token::kMUL);
|
| }
|
|
|
| -
|
| void Intrinsifier::Double_sub(Assembler* assembler) {
|
| DoubleArithmeticOperations(assembler, Token::kSUB);
|
| }
|
|
|
| -
|
| void Intrinsifier::Double_div(Assembler* assembler) {
|
| DoubleArithmeticOperations(assembler, Token::kDIV);
|
| }
|
|
|
| -
|
| void Intrinsifier::Double_mulFromInteger(Assembler* assembler) {
|
| Label fall_through;
|
| // Only smis allowed.
|
| @@ -1401,7 +1341,6 @@ void Intrinsifier::Double_mulFromInteger(Assembler* assembler) {
|
| __ Bind(&fall_through);
|
| }
|
|
|
| -
|
| // Left is double right is integer (Bigint, Mint or Smi)
|
| void Intrinsifier::DoubleFromInteger(Assembler* assembler) {
|
| Label fall_through;
|
| @@ -1421,7 +1360,6 @@ void Intrinsifier::DoubleFromInteger(Assembler* assembler) {
|
| __ Bind(&fall_through);
|
| }
|
|
|
| -
|
| void Intrinsifier::Double_getIsNaN(Assembler* assembler) {
|
| Label is_true;
|
| __ movq(RAX, Address(RSP, +1 * kWordSize));
|
| @@ -1435,7 +1373,6 @@ void Intrinsifier::Double_getIsNaN(Assembler* assembler) {
|
| __ ret();
|
| }
|
|
|
| -
|
| void Intrinsifier::Double_getIsInfinite(Assembler* assembler) {
|
| Label is_inf, done;
|
| __ movq(RAX, Address(RSP, +1 * kWordSize));
|
| @@ -1455,7 +1392,6 @@ void Intrinsifier::Double_getIsInfinite(Assembler* assembler) {
|
| __ ret();
|
| }
|
|
|
| -
|
| void Intrinsifier::Double_getIsNegative(Assembler* assembler) {
|
| Label is_false, is_true, is_zero;
|
| __ movq(RAX, Address(RSP, +1 * kWordSize));
|
| @@ -1479,7 +1415,6 @@ void Intrinsifier::Double_getIsNegative(Assembler* assembler) {
|
| __ jmp(&is_false, Assembler::kNearJump);
|
| }
|
|
|
| -
|
| void Intrinsifier::DoubleToInteger(Assembler* assembler) {
|
| __ movq(RAX, Address(RSP, +1 * kWordSize));
|
| __ movsd(XMM0, FieldAddress(RAX, Double::value_offset()));
|
| @@ -1495,7 +1430,6 @@ void Intrinsifier::DoubleToInteger(Assembler* assembler) {
|
| __ Bind(&fall_through);
|
| }
|
|
|
| -
|
| void Intrinsifier::MathSqrt(Assembler* assembler) {
|
| Label fall_through, is_smi, double_op;
|
| TestLastArgumentIsDouble(assembler, &is_smi, &fall_through);
|
| @@ -1517,7 +1451,6 @@ void Intrinsifier::MathSqrt(Assembler* assembler) {
|
| __ Bind(&fall_through);
|
| }
|
|
|
| -
|
| // var state = ((_A * (_state[kSTATE_LO])) + _state[kSTATE_HI]) & _MASK_64;
|
| // _state[kSTATE_LO] = state & _MASK_32;
|
| // _state[kSTATE_HI] = state >> 32;
|
| @@ -1577,7 +1510,6 @@ void Intrinsifier::ObjectEquals(Assembler* assembler) {
|
| __ ret();
|
| }
|
|
|
| -
|
| static void RangeCheck(Assembler* assembler,
|
| Register reg,
|
| intptr_t low,
|
| @@ -1589,35 +1521,29 @@ static void RangeCheck(Assembler* assembler,
|
| __ j(cc, target);
|
| }
|
|
|
| -
|
| const Condition kIfNotInRange = ABOVE;
|
| const Condition kIfInRange = BELOW_EQUAL;
|
|
|
| -
|
| static void JumpIfInteger(Assembler* assembler, Register cid, Label* target) {
|
| RangeCheck(assembler, cid, kSmiCid, kBigintCid, kIfInRange, target);
|
| }
|
|
|
| -
|
| static void JumpIfNotInteger(Assembler* assembler,
|
| Register cid,
|
| Label* target) {
|
| RangeCheck(assembler, cid, kSmiCid, kBigintCid, kIfNotInRange, target);
|
| }
|
|
|
| -
|
| static void JumpIfString(Assembler* assembler, Register cid, Label* target) {
|
| RangeCheck(assembler, cid, kOneByteStringCid, kExternalTwoByteStringCid,
|
| kIfInRange, target);
|
| }
|
|
|
| -
|
| static void JumpIfNotString(Assembler* assembler, Register cid, Label* target) {
|
| RangeCheck(assembler, cid, kOneByteStringCid, kExternalTwoByteStringCid,
|
| kIfNotInRange, target);
|
| }
|
|
|
| -
|
| // Return type quickly for simple types (not parameterized and not signature).
|
| void Intrinsifier::ObjectRuntimeType(Assembler* assembler) {
|
| Label fall_through, use_canonical_type, not_integer, not_double;
|
| @@ -1675,7 +1601,6 @@ void Intrinsifier::ObjectRuntimeType(Assembler* assembler) {
|
| __ Bind(&fall_through);
|
| }
|
|
|
| -
|
| void Intrinsifier::ObjectHaveSameRuntimeType(Assembler* assembler) {
|
| Label fall_through, different_cids, equal, not_equal, not_integer;
|
|
|
| @@ -1739,7 +1664,6 @@ void Intrinsifier::ObjectHaveSameRuntimeType(Assembler* assembler) {
|
| __ Bind(&fall_through);
|
| }
|
|
|
| -
|
| void Intrinsifier::String_getHashCode(Assembler* assembler) {
|
| Label fall_through;
|
| __ movq(RAX, Address(RSP, +1 * kWordSize)); // String object.
|
| @@ -1753,7 +1677,6 @@ void Intrinsifier::String_getHashCode(Assembler* assembler) {
|
| // Hash not yet computed.
|
| }
|
|
|
| -
|
| void Intrinsifier::Object_getHash(Assembler* assembler) {
|
| __ movq(RAX, Address(RSP, +1 * kWordSize)); // Object.
|
| __ movl(RAX, FieldAddress(RAX, String::hash_offset()));
|
| @@ -1761,7 +1684,6 @@ void Intrinsifier::Object_getHash(Assembler* assembler) {
|
| __ ret();
|
| }
|
|
|
| -
|
| void Intrinsifier::Object_setHash(Assembler* assembler) {
|
| __ movq(RAX, Address(RSP, +2 * kWordSize)); // Object.
|
| __ movq(RDX, Address(RSP, +1 * kWordSize)); // Value.
|
| @@ -1770,7 +1692,6 @@ void Intrinsifier::Object_setHash(Assembler* assembler) {
|
| __ ret();
|
| }
|
|
|
| -
|
| void GenerateSubstringMatchesSpecialization(Assembler* assembler,
|
| intptr_t receiver_cid,
|
| intptr_t other_cid,
|
| @@ -1833,7 +1754,6 @@ void GenerateSubstringMatchesSpecialization(Assembler* assembler,
|
| __ jmp(return_true);
|
| }
|
|
|
| -
|
| // bool _substringMatches(int start, String other)
|
| // This intrinsic handles a OneByteString or TwoByteString receiver with a
|
| // OneByteString other.
|
| @@ -1875,7 +1795,6 @@ void Intrinsifier::StringBaseSubstringMatches(Assembler* assembler) {
|
| __ Bind(&fall_through);
|
| }
|
|
|
| -
|
| void Intrinsifier::StringBaseCharAt(Assembler* assembler) {
|
| Label fall_through, try_two_byte_string;
|
| __ movq(RCX, Address(RSP, +1 * kWordSize)); // Index.
|
| @@ -1912,7 +1831,6 @@ void Intrinsifier::StringBaseCharAt(Assembler* assembler) {
|
| __ Bind(&fall_through);
|
| }
|
|
|
| -
|
| void Intrinsifier::StringBaseIsEmpty(Assembler* assembler) {
|
| Label is_true;
|
| // Get length.
|
| @@ -1927,7 +1845,6 @@ void Intrinsifier::StringBaseIsEmpty(Assembler* assembler) {
|
| __ ret();
|
| }
|
|
|
| -
|
| void Intrinsifier::OneByteString_getHashCode(Assembler* assembler) {
|
| Label compute_hash;
|
| __ movq(RBX, Address(RSP, +1 * kWordSize)); // OneByteString object.
|
| @@ -1997,7 +1914,6 @@ void Intrinsifier::OneByteString_getHashCode(Assembler* assembler) {
|
| __ ret();
|
| }
|
|
|
| -
|
| // Allocates one-byte string of length 'end - start'. The content is not
|
| // initialized. 'length-reg' contains tagged length.
|
| // Returns new string as tagged pointer in RAX.
|
| @@ -2010,7 +1926,7 @@ static void TryAllocateOnebyteString(Assembler* assembler,
|
| __ movq(RDI, length_reg);
|
| }
|
| Label pop_and_fail, not_zero_length;
|
| - __ pushq(RDI); // Preserve length.
|
| + __ pushq(RDI); // Preserve length.
|
| __ sarq(RDI, Immediate(kSmiTagShift)); // Untag length.
|
| // If the length is 0 then we have to make the allocated size a bit bigger,
|
| // otherwise the string takes up less space than an ExternalOneByteString,
|
| @@ -2079,7 +1995,6 @@ static void TryAllocateOnebyteString(Assembler* assembler,
|
| __ jmp(failure);
|
| }
|
|
|
| -
|
| // Arg0: OneByteString (receiver).
|
| // Arg1: Start index as Smi.
|
| // Arg2: End index as Smi.
|
| @@ -2128,7 +2043,6 @@ void Intrinsifier::OneByteString_substringUnchecked(Assembler* assembler) {
|
| __ Bind(&fall_through);
|
| }
|
|
|
| -
|
| void Intrinsifier::OneByteStringSetAt(Assembler* assembler) {
|
| __ movq(RCX, Address(RSP, +1 * kWordSize)); // Value.
|
| __ movq(RBX, Address(RSP, +2 * kWordSize)); // Index.
|
| @@ -2139,7 +2053,6 @@ void Intrinsifier::OneByteStringSetAt(Assembler* assembler) {
|
| __ ret();
|
| }
|
|
|
| -
|
| void Intrinsifier::OneByteString_allocate(Assembler* assembler) {
|
| __ movq(RDI, Address(RSP, +1 * kWordSize)); // Length.v=
|
| Label fall_through, ok;
|
| @@ -2152,7 +2065,6 @@ void Intrinsifier::OneByteString_allocate(Assembler* assembler) {
|
| __ Bind(&fall_through);
|
| }
|
|
|
| -
|
| // TODO(srdjan): Add combinations (one-byte/two-byte/external strings).
|
| static void StringEquality(Assembler* assembler, intptr_t string_cid) {
|
| Label fall_through, is_true, is_false, loop;
|
| @@ -2209,17 +2121,14 @@ static void StringEquality(Assembler* assembler, intptr_t string_cid) {
|
| __ Bind(&fall_through);
|
| }
|
|
|
| -
|
| void Intrinsifier::OneByteString_equality(Assembler* assembler) {
|
| StringEquality(assembler, kOneByteStringCid);
|
| }
|
|
|
| -
|
| void Intrinsifier::TwoByteString_equality(Assembler* assembler) {
|
| StringEquality(assembler, kTwoByteStringCid);
|
| }
|
|
|
| -
|
| void Intrinsifier::IntrinsifyRegExpExecuteMatch(Assembler* assembler,
|
| bool sticky) {
|
| if (FLAG_interpret_irregexp) return;
|
| @@ -2239,8 +2148,9 @@ void Intrinsifier::IntrinsifyRegExpExecuteMatch(Assembler* assembler,
|
| __ movq(RDI, Address(RSP, kStringParamOffset));
|
| __ LoadClassId(RDI, RDI);
|
| __ SubImmediate(RDI, Immediate(kOneByteStringCid));
|
| - __ movq(RAX, FieldAddress(RBX, RDI, TIMES_8, RegExp::function_offset(
|
| - kOneByteStringCid, sticky)));
|
| + __ movq(RAX,
|
| + FieldAddress(RBX, RDI, TIMES_8,
|
| + RegExp::function_offset(kOneByteStringCid, sticky)));
|
|
|
| // Registers are now set up for the lazy compile stub. It expects the function
|
| // in RAX, the argument descriptor in R10, and IC-Data in RCX.
|
| @@ -2252,7 +2162,6 @@ void Intrinsifier::IntrinsifyRegExpExecuteMatch(Assembler* assembler,
|
| __ jmp(RDI);
|
| }
|
|
|
| -
|
| // On stack: user tag (+1), return-address (+0).
|
| void Intrinsifier::UserTag_makeCurrent(Assembler* assembler) {
|
| // RBX: Isolate.
|
| @@ -2270,21 +2179,18 @@ void Intrinsifier::UserTag_makeCurrent(Assembler* assembler) {
|
| __ ret();
|
| }
|
|
|
| -
|
| void Intrinsifier::UserTag_defaultTag(Assembler* assembler) {
|
| __ LoadIsolate(RAX);
|
| __ movq(RAX, Address(RAX, Isolate::default_tag_offset()));
|
| __ ret();
|
| }
|
|
|
| -
|
| void Intrinsifier::Profiler_getCurrentTag(Assembler* assembler) {
|
| __ LoadIsolate(RAX);
|
| __ movq(RAX, Address(RAX, Isolate::current_tag_offset()));
|
| __ ret();
|
| }
|
|
|
| -
|
| void Intrinsifier::Timeline_isDartStreamEnabled(Assembler* assembler) {
|
| if (!FLAG_support_timeline) {
|
| __ LoadObject(RAX, Bool::False());
|
| @@ -2307,14 +2213,12 @@ void Intrinsifier::Timeline_isDartStreamEnabled(Assembler* assembler) {
|
| __ ret();
|
| }
|
|
|
| -
|
| void Intrinsifier::ClearAsyncThreadStackTrace(Assembler* assembler) {
|
| __ LoadObject(RAX, Object::null_object());
|
| __ movq(Address(THR, Thread::async_stack_trace_offset()), RAX);
|
| __ ret();
|
| }
|
|
|
| -
|
| void Intrinsifier::SetAsyncThreadStackTrace(Assembler* assembler) {
|
| __ movq(Address(THR, Thread::async_stack_trace_offset()), RAX);
|
| __ LoadObject(RAX, Object::null_object());
|
|
|