[ptr-compr][arm64] Preparing for using smi-corrupting decompression
This CL fixes comparison operations that take into account full-word value instead of the lower 32 bits. Bug: v8:9706 Change-Id: I9176ea1ece7c0551b1fa6b9df58445ba49434234 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1824474 Commit-Queue: Igor Sheludko <ishell@chromium.org> Reviewed-by: Toon Verwaest <verwaest@chromium.org> Cr-Commit-Position: refs/heads/master@{#64006}
This commit is contained in:
parent
318d66d95f
commit
0cf720862a
@ -1001,7 +1001,8 @@ static void TailCallRuntimeIfMarkerEquals(MacroAssembler* masm,
|
||||
OptimizationMarker marker,
|
||||
Runtime::FunctionId function_id) {
|
||||
Label no_match;
|
||||
__ CompareAndBranch(smi_entry, Operand(Smi::FromEnum(marker)), ne, &no_match);
|
||||
__ CompareTaggedAndBranch(smi_entry, Operand(Smi::FromEnum(marker)), ne,
|
||||
&no_match);
|
||||
GenerateTailCallToReturnedCode(masm, function_id);
|
||||
__ bind(&no_match);
|
||||
}
|
||||
@ -1036,9 +1037,9 @@ static void MaybeTailCallOptimizedCodeSlot(MacroAssembler* masm,
|
||||
// Optimized code slot is a Smi optimization marker.
|
||||
|
||||
// Fall through if no optimization trigger.
|
||||
__ CompareAndBranch(optimized_code_entry,
|
||||
Operand(Smi::FromEnum(OptimizationMarker::kNone)), eq,
|
||||
&fallthrough);
|
||||
__ CompareTaggedAndBranch(optimized_code_entry,
|
||||
Operand(Smi::FromEnum(OptimizationMarker::kNone)),
|
||||
eq, &fallthrough);
|
||||
|
||||
// TODO(v8:8394): The logging of first execution will break if
|
||||
// feedback vectors are not allocated. We need to find a different way of
|
||||
@ -1058,7 +1059,7 @@ static void MaybeTailCallOptimizedCodeSlot(MacroAssembler* masm,
|
||||
// Otherwise, the marker is InOptimizationQueue, so fall through hoping
|
||||
// that an interrupt will eventually update the slot with optimized code.
|
||||
if (FLAG_debug_code) {
|
||||
__ Cmp(
|
||||
__ CmpTagged(
|
||||
optimized_code_entry,
|
||||
Operand(Smi::FromEnum(OptimizationMarker::kInOptimizationQueue)));
|
||||
__ Assert(eq, AbortReason::kExpectedOptimizationSentinel);
|
||||
@ -1634,7 +1635,7 @@ void Builtins::Generate_InstantiateAsmJs(MacroAssembler* masm) {
|
||||
|
||||
// Set flags for determining the value of smi-tagged argc.
|
||||
// lt => 1, eq => 2, gt => 3.
|
||||
__ Cmp(argc, Smi::FromInt(2));
|
||||
__ CmpTagged(argc, Smi::FromInt(2));
|
||||
__ B(gt, &three_args);
|
||||
|
||||
// One or two arguments.
|
||||
@ -1783,7 +1784,7 @@ void Builtins::Generate_InterpreterOnStackReplacement(MacroAssembler* masm) {
|
||||
|
||||
// If the code object is null, just return to the caller.
|
||||
Label skip;
|
||||
__ CompareAndBranch(x0, Smi::zero(), ne, &skip);
|
||||
__ CompareTaggedAndBranch(x0, Smi::zero(), ne, &skip);
|
||||
__ Ret();
|
||||
|
||||
__ Bind(&skip);
|
||||
@ -1879,8 +1880,8 @@ void Builtins::Generate_FunctionPrototypeApply(MacroAssembler* masm) {
|
||||
|
||||
// 3. Tail call with no arguments if argArray is null or undefined.
|
||||
Label no_arguments;
|
||||
__ Cmp(arg_array, null_value);
|
||||
__ Ccmp(arg_array, undefined_value, ZFlag, ne);
|
||||
__ CmpTagged(arg_array, null_value);
|
||||
__ CcmpTagged(arg_array, undefined_value, ZFlag, ne);
|
||||
__ B(eq, &no_arguments);
|
||||
|
||||
// 4a. Apply the receiver to the given argArray.
|
||||
@ -2262,7 +2263,7 @@ void Builtins::Generate_CallOrConstructVarargs(MacroAssembler* masm,
|
||||
__ Bind(&loop);
|
||||
__ Sub(len, len, 1);
|
||||
__ LoadAnyTaggedField(scratch, MemOperand(src, kTaggedSize, PostIndex));
|
||||
__ Cmp(scratch, the_hole_value);
|
||||
__ CmpTagged(scratch, the_hole_value);
|
||||
__ Csel(scratch, scratch, undefined_value, ne);
|
||||
__ Poke(scratch, Operand(len, LSL, kSystemPointerSizeLog2));
|
||||
__ Cbnz(len, &loop);
|
||||
@ -2320,7 +2321,7 @@ void Builtins::Generate_CallOrConstructForwardVarargs(MacroAssembler* masm,
|
||||
__ Ldr(args_fp, MemOperand(fp, StandardFrameConstants::kCallerFPOffset));
|
||||
__ Ldr(x4, MemOperand(args_fp,
|
||||
CommonFrameConstants::kContextOrFrameTypeOffset));
|
||||
__ Cmp(x4, StackFrame::TypeToMarker(StackFrame::ARGUMENTS_ADAPTOR));
|
||||
__ CmpTagged(x4, StackFrame::TypeToMarker(StackFrame::ARGUMENTS_ADAPTOR));
|
||||
__ B(eq, &arguments_adaptor);
|
||||
{
|
||||
__ Ldr(scratch,
|
||||
@ -2711,7 +2712,7 @@ void Builtins::Generate_ConstructBoundFunction(MacroAssembler* masm) {
|
||||
// Patch new.target to [[BoundTargetFunction]] if new.target equals target.
|
||||
{
|
||||
Label done;
|
||||
__ Cmp(x1, x3);
|
||||
__ CmpTagged(x1, x3);
|
||||
__ B(ne, &done);
|
||||
__ LoadTaggedPointerField(
|
||||
x3, FieldMemOperand(x1, JSBoundFunction::kBoundTargetFunctionOffset));
|
||||
|
@ -308,6 +308,18 @@ Operand Operand::ToExtendedRegister() const {
|
||||
return Operand(reg_, reg_.Is64Bits() ? UXTX : UXTW, shift_amount_);
|
||||
}
|
||||
|
||||
Operand Operand::ToW() const {
|
||||
if (IsShiftedRegister()) {
|
||||
DCHECK(reg_.Is64Bits());
|
||||
return Operand(reg_.W(), shift(), shift_amount());
|
||||
} else if (IsExtendedRegister()) {
|
||||
DCHECK(reg_.Is64Bits());
|
||||
return Operand(reg_.W(), extend(), shift_amount());
|
||||
}
|
||||
DCHECK(IsImmediate());
|
||||
return *this;
|
||||
}
|
||||
|
||||
Immediate Operand::immediate_for_heap_object_request() const {
|
||||
DCHECK((heap_object_request().kind() == HeapObjectRequest::kHeapNumber &&
|
||||
immediate_.rmode() == RelocInfo::FULL_EMBEDDED_OBJECT) ||
|
||||
|
@ -106,6 +106,9 @@ class Operand {
|
||||
// which helps in the encoding of instructions that use the stack pointer.
|
||||
inline Operand ToExtendedRegister() const;
|
||||
|
||||
// Returns new Operand adapted for using with W registers.
|
||||
inline Operand ToW() const;
|
||||
|
||||
inline Immediate immediate() const;
|
||||
inline int64_t ImmediateValue() const;
|
||||
inline RelocInfo::Mode ImmediateRMode() const;
|
||||
|
@ -93,6 +93,15 @@ void TurboAssembler::Ccmp(const Register& rn, const Operand& operand,
|
||||
}
|
||||
}
|
||||
|
||||
void TurboAssembler::CcmpTagged(const Register& rn, const Operand& operand,
|
||||
StatusFlags nzcv, Condition cond) {
|
||||
if (COMPRESS_POINTERS_BOOL) {
|
||||
Ccmp(rn.W(), operand.ToW(), nzcv, cond);
|
||||
} else {
|
||||
Ccmp(rn, operand, nzcv, cond);
|
||||
}
|
||||
}
|
||||
|
||||
void MacroAssembler::Ccmn(const Register& rn, const Operand& operand,
|
||||
StatusFlags nzcv, Condition cond) {
|
||||
DCHECK(allow_macro_instructions());
|
||||
@ -157,6 +166,14 @@ void TurboAssembler::Cmp(const Register& rn, const Operand& operand) {
|
||||
Subs(AppropriateZeroRegFor(rn), rn, operand);
|
||||
}
|
||||
|
||||
void TurboAssembler::CmpTagged(const Register& rn, const Operand& operand) {
|
||||
if (COMPRESS_POINTERS_BOOL) {
|
||||
Cmp(rn.W(), operand.ToW());
|
||||
} else {
|
||||
Cmp(rn, operand);
|
||||
}
|
||||
}
|
||||
|
||||
void TurboAssembler::Neg(const Register& rd, const Operand& operand) {
|
||||
DCHECK(allow_macro_instructions());
|
||||
DCHECK(!rd.IsZero());
|
||||
@ -982,7 +999,12 @@ void TurboAssembler::SmiUntag(Register dst, Register src) {
|
||||
AssertSmi(src);
|
||||
}
|
||||
DCHECK(SmiValuesAre32Bits() || SmiValuesAre31Bits());
|
||||
Asr(dst, src, kSmiShift);
|
||||
if (COMPRESS_POINTERS_BOOL) {
|
||||
Asr(dst.W(), src.W(), kSmiShift);
|
||||
Sxtw(dst, dst);
|
||||
} else {
|
||||
Asr(dst, src, kSmiShift);
|
||||
}
|
||||
}
|
||||
|
||||
void TurboAssembler::SmiUntag(Register dst, const MemOperand& src) {
|
||||
@ -1002,11 +1024,11 @@ void TurboAssembler::SmiUntag(Register dst, const MemOperand& src) {
|
||||
}
|
||||
} else {
|
||||
DCHECK(SmiValuesAre31Bits());
|
||||
#ifdef V8_COMPRESS_POINTERS
|
||||
Ldrsw(dst, src);
|
||||
#else
|
||||
Ldr(dst, src);
|
||||
#endif
|
||||
if (COMPRESS_POINTERS_BOOL) {
|
||||
Ldrsw(dst, src);
|
||||
} else {
|
||||
Ldr(dst, src);
|
||||
}
|
||||
SmiUntag(dst);
|
||||
}
|
||||
}
|
||||
@ -1190,6 +1212,16 @@ void MacroAssembler::CompareAndBranch(const Register& lhs, const Operand& rhs,
|
||||
}
|
||||
}
|
||||
|
||||
void MacroAssembler::CompareTaggedAndBranch(const Register& lhs,
|
||||
const Operand& rhs, Condition cond,
|
||||
Label* label) {
|
||||
if (COMPRESS_POINTERS_BOOL) {
|
||||
CompareAndBranch(lhs.W(), rhs.ToW(), cond, label);
|
||||
} else {
|
||||
CompareAndBranch(lhs, rhs, cond, label);
|
||||
}
|
||||
}
|
||||
|
||||
void TurboAssembler::TestAndBranchIfAnySet(const Register& reg,
|
||||
const uint64_t bit_pattern,
|
||||
Label* label) {
|
||||
|
@ -1923,21 +1923,25 @@ void TurboAssembler::Call(ExternalReference target) {
|
||||
}
|
||||
|
||||
void TurboAssembler::LoadEntryFromBuiltinIndex(Register builtin_index) {
|
||||
STATIC_ASSERT(kSystemPointerSize == 8);
|
||||
STATIC_ASSERT(kSmiTagSize == 1);
|
||||
STATIC_ASSERT(kSmiTag == 0);
|
||||
|
||||
// The builtin_index register contains the builtin index as a Smi.
|
||||
// Untagging is folded into the indexing operand below.
|
||||
#if defined(V8_COMPRESS_POINTERS) || defined(V8_31BIT_SMIS_ON_64BIT_ARCH)
|
||||
STATIC_ASSERT(kSmiShiftSize == 0);
|
||||
Lsl(builtin_index, builtin_index, kSystemPointerSizeLog2 - kSmiShift);
|
||||
#else
|
||||
STATIC_ASSERT(kSmiShiftSize == 31);
|
||||
Asr(builtin_index, builtin_index, kSmiShift - kSystemPointerSizeLog2);
|
||||
#endif
|
||||
Add(builtin_index, builtin_index, IsolateData::builtin_entry_table_offset());
|
||||
Ldr(builtin_index, MemOperand(kRootRegister, builtin_index));
|
||||
if (SmiValuesAre32Bits()) {
|
||||
Asr(builtin_index, builtin_index, kSmiShift - kSystemPointerSizeLog2);
|
||||
Add(builtin_index, builtin_index,
|
||||
IsolateData::builtin_entry_table_offset());
|
||||
Ldr(builtin_index, MemOperand(kRootRegister, builtin_index));
|
||||
} else {
|
||||
DCHECK(SmiValuesAre31Bits());
|
||||
if (COMPRESS_POINTERS_BOOL) {
|
||||
Add(builtin_index, kRootRegister,
|
||||
Operand(builtin_index.W(), SXTW, kSystemPointerSizeLog2 - kSmiShift));
|
||||
} else {
|
||||
Add(builtin_index, kRootRegister,
|
||||
Operand(builtin_index, LSL, kSystemPointerSizeLog2 - kSmiShift));
|
||||
}
|
||||
Ldr(builtin_index,
|
||||
MemOperand(builtin_index, IsolateData::builtin_entry_table_offset()));
|
||||
}
|
||||
}
|
||||
|
||||
void TurboAssembler::CallBuiltinByIndex(Register builtin_index) {
|
||||
@ -2636,7 +2640,7 @@ void MacroAssembler::CompareRoot(const Register& obj, RootIndex index) {
|
||||
Register temp = temps.AcquireX();
|
||||
DCHECK(!AreAliased(obj, temp));
|
||||
LoadRoot(temp, index);
|
||||
Cmp(obj, temp);
|
||||
CmpTagged(obj, temp);
|
||||
}
|
||||
|
||||
void MacroAssembler::JumpIfRoot(const Register& obj, RootIndex index,
|
||||
@ -2669,20 +2673,20 @@ void MacroAssembler::JumpIfIsInRange(const Register& value,
|
||||
|
||||
void TurboAssembler::LoadTaggedPointerField(const Register& destination,
|
||||
const MemOperand& field_operand) {
|
||||
#ifdef V8_COMPRESS_POINTERS
|
||||
DecompressTaggedPointer(destination, field_operand);
|
||||
#else
|
||||
Ldr(destination, field_operand);
|
||||
#endif
|
||||
if (COMPRESS_POINTERS_BOOL) {
|
||||
DecompressTaggedPointer(destination, field_operand);
|
||||
} else {
|
||||
Ldr(destination, field_operand);
|
||||
}
|
||||
}
|
||||
|
||||
void TurboAssembler::LoadAnyTaggedField(const Register& destination,
|
||||
const MemOperand& field_operand) {
|
||||
#ifdef V8_COMPRESS_POINTERS
|
||||
DecompressAnyTagged(destination, field_operand);
|
||||
#else
|
||||
Ldr(destination, field_operand);
|
||||
#endif
|
||||
if (COMPRESS_POINTERS_BOOL) {
|
||||
DecompressAnyTagged(destination, field_operand);
|
||||
} else {
|
||||
Ldr(destination, field_operand);
|
||||
}
|
||||
}
|
||||
|
||||
void TurboAssembler::SmiUntagField(Register dst, const MemOperand& src) {
|
||||
@ -2691,13 +2695,11 @@ void TurboAssembler::SmiUntagField(Register dst, const MemOperand& src) {
|
||||
|
||||
void TurboAssembler::StoreTaggedField(const Register& value,
|
||||
const MemOperand& dst_field_operand) {
|
||||
#ifdef V8_COMPRESS_POINTERS
|
||||
RecordComment("[ StoreTagged");
|
||||
Str(value.W(), dst_field_operand);
|
||||
RecordComment("]");
|
||||
#else
|
||||
Str(value, dst_field_operand);
|
||||
#endif
|
||||
if (COMPRESS_POINTERS_BOOL) {
|
||||
Str(value.W(), dst_field_operand);
|
||||
} else {
|
||||
Str(value, dst_field_operand);
|
||||
}
|
||||
}
|
||||
|
||||
void TurboAssembler::DecompressTaggedSigned(const Register& destination,
|
||||
|
@ -652,6 +652,7 @@ class V8_EXPORT_PRIVATE TurboAssembler : public TurboAssemblerBase {
|
||||
const Operand& operand);
|
||||
inline void Blr(const Register& xn);
|
||||
inline void Cmp(const Register& rn, const Operand& operand);
|
||||
inline void CmpTagged(const Register& rn, const Operand& operand);
|
||||
inline void Subs(const Register& rd, const Register& rn,
|
||||
const Operand& operand);
|
||||
void Csel(const Register& rd, const Register& rn, const Operand& operand,
|
||||
@ -1006,6 +1007,8 @@ class V8_EXPORT_PRIVATE TurboAssembler : public TurboAssemblerBase {
|
||||
// Conditional macros.
|
||||
inline void Ccmp(const Register& rn, const Operand& operand, StatusFlags nzcv,
|
||||
Condition cond);
|
||||
inline void CcmpTagged(const Register& rn, const Operand& operand,
|
||||
StatusFlags nzcv, Condition cond);
|
||||
|
||||
inline void Clz(const Register& rd, const Register& rn);
|
||||
|
||||
@ -1645,6 +1648,8 @@ class V8_EXPORT_PRIVATE MacroAssembler : public TurboAssembler {
|
||||
// condition. May corrupt the status flags.
|
||||
inline void CompareAndBranch(const Register& lhs, const Operand& rhs,
|
||||
Condition cond, Label* label);
|
||||
inline void CompareTaggedAndBranch(const Register& lhs, const Operand& rhs,
|
||||
Condition cond, Label* label);
|
||||
|
||||
// Insert one or more instructions into the instruction stream that encode
|
||||
// some caller-defined data. The instructions used will be executable with no
|
||||
|
Loading…
Reference in New Issue
Block a user