Commit 2ef4e3d7 authored by Santiago Aboy Solanes's avatar Santiago Aboy Solanes Committed by Commit Bot

[ptr-compr][arm64] Introduce bottlenecks for accessing on-heap tagged fields.

This CL introduces TurboAssembler::LoadTaggedPointerField() and
TurboAssembler::LoadAnyTaggedField(), which respectively loads a field
containing a HeapObject, or any tagged value, and decompresses it if necessary.

Bug: v8:7703
Change-Id: I71ace74d7433a3a78d56bdcef6d2ec041df630e4
Reviewed-on: https://chromium-review.googlesource.com/c/1456098
Commit-Queue: Santiago Aboy Solanes <solanes@chromium.org>
Reviewed-by: 's avatarJakob Gruber <jgruber@chromium.org>
Reviewed-by: 's avatarSigurd Schneider <sigurds@chromium.org>
Reviewed-by: 's avatarIgor Sheludko <ishell@chromium.org>
Reviewed-by: 's avatarRoss McIlroy <rmcilroy@chromium.org>
Cr-Commit-Position: refs/heads/master@{#59501}
parent 62b85421
...@@ -1616,7 +1616,8 @@ void MacroAssembler::AssertConstructor(Register object) { ...@@ -1616,7 +1616,8 @@ void MacroAssembler::AssertConstructor(Register object) {
UseScratchRegisterScope temps(this); UseScratchRegisterScope temps(this);
Register temp = temps.AcquireX(); Register temp = temps.AcquireX();
Ldr(temp, FieldMemOperand(object, HeapObject::kMapOffset)); LoadTaggedPointerField(temp,
FieldMemOperand(object, HeapObject::kMapOffset));
Ldrb(temp, FieldMemOperand(temp, Map::kBitFieldOffset)); Ldrb(temp, FieldMemOperand(temp, Map::kBitFieldOffset));
Tst(temp, Operand(Map::IsConstructorBit::kMask)); Tst(temp, Operand(Map::IsConstructorBit::kMask));
...@@ -1656,7 +1657,7 @@ void MacroAssembler::AssertGeneratorObject(Register object) { ...@@ -1656,7 +1657,7 @@ void MacroAssembler::AssertGeneratorObject(Register object) {
// Load map // Load map
UseScratchRegisterScope temps(this); UseScratchRegisterScope temps(this);
Register temp = temps.AcquireX(); Register temp = temps.AcquireX();
Ldr(temp, FieldMemOperand(object, HeapObject::kMapOffset)); LoadTaggedPointerField(temp, FieldMemOperand(object, HeapObject::kMapOffset));
Label do_check; Label do_check;
// Load instance type and check if JSGeneratorObject // Load instance type and check if JSGeneratorObject
...@@ -1682,7 +1683,8 @@ void MacroAssembler::AssertUndefinedOrAllocationSite(Register object) { ...@@ -1682,7 +1683,8 @@ void MacroAssembler::AssertUndefinedOrAllocationSite(Register object) {
Label done_checking; Label done_checking;
AssertNotSmi(object); AssertNotSmi(object);
JumpIfRoot(object, RootIndex::kUndefinedValue, &done_checking); JumpIfRoot(object, RootIndex::kUndefinedValue, &done_checking);
Ldr(scratch, FieldMemOperand(object, HeapObject::kMapOffset)); LoadTaggedPointerField(scratch,
FieldMemOperand(object, HeapObject::kMapOffset));
CompareInstanceType(scratch, scratch, ALLOCATION_SITE_TYPE); CompareInstanceType(scratch, scratch, ALLOCATION_SITE_TYPE);
Assert(eq, AbortReason::kExpectedUndefinedOrCell); Assert(eq, AbortReason::kExpectedUndefinedOrCell);
Bind(&done_checking); Bind(&done_checking);
...@@ -1848,9 +1850,9 @@ void TurboAssembler::LoadFromConstantsTable(Register destination, ...@@ -1848,9 +1850,9 @@ void TurboAssembler::LoadFromConstantsTable(Register destination,
int constant_index) { int constant_index) {
DCHECK(RootsTable::IsImmortalImmovable(RootIndex::kBuiltinsConstantsTable)); DCHECK(RootsTable::IsImmortalImmovable(RootIndex::kBuiltinsConstantsTable));
LoadRoot(destination, RootIndex::kBuiltinsConstantsTable); LoadRoot(destination, RootIndex::kBuiltinsConstantsTable);
Ldr(destination, LoadTaggedPointerField(
FieldMemOperand(destination, destination, FieldMemOperand(destination, FixedArray::OffsetOfElementAt(
FixedArray::kHeaderSize + constant_index * kPointerSize)); constant_index)));
} }
void TurboAssembler::LoadRootRelative(Register destination, int32_t offset) { void TurboAssembler::LoadRootRelative(Register destination, int32_t offset) {
...@@ -2357,7 +2359,8 @@ void MacroAssembler::InvokeFunctionCode(Register function, Register new_target, ...@@ -2357,7 +2359,8 @@ void MacroAssembler::InvokeFunctionCode(Register function, Register new_target,
// allow recompilation to take effect without changing any of the // allow recompilation to take effect without changing any of the
// call sites. // call sites.
Register code = kJavaScriptCallCodeStartRegister; Register code = kJavaScriptCallCodeStartRegister;
Ldr(code, FieldMemOperand(function, JSFunction::kCodeOffset)); LoadTaggedPointerField(code,
FieldMemOperand(function, JSFunction::kCodeOffset));
if (flag == CALL_FUNCTION) { if (flag == CALL_FUNCTION) {
CallCodeObject(code); CallCodeObject(code);
} else { } else {
...@@ -2383,12 +2386,14 @@ void MacroAssembler::InvokeFunction(Register function, Register new_target, ...@@ -2383,12 +2386,14 @@ void MacroAssembler::InvokeFunction(Register function, Register new_target,
Register expected_reg = x2; Register expected_reg = x2;
Ldr(cp, FieldMemOperand(function, JSFunction::kContextOffset)); LoadTaggedPointerField(cp,
FieldMemOperand(function, JSFunction::kContextOffset));
// The number of arguments is stored as an int32_t, and -1 is a marker // The number of arguments is stored as an int32_t, and -1 is a marker
// (SharedFunctionInfo::kDontAdaptArgumentsSentinel), so we need sign // (SharedFunctionInfo::kDontAdaptArgumentsSentinel), so we need sign
// extension to correctly handle it. // extension to correctly handle it.
Ldr(expected_reg, FieldMemOperand(function, LoadTaggedPointerField(
JSFunction::kSharedFunctionInfoOffset)); expected_reg,
FieldMemOperand(function, JSFunction::kSharedFunctionInfoOffset));
Ldrh(expected_reg, Ldrh(expected_reg,
FieldMemOperand(expected_reg, FieldMemOperand(expected_reg,
SharedFunctionInfo::kFormalParameterCountOffset)); SharedFunctionInfo::kFormalParameterCountOffset));
...@@ -2409,7 +2414,8 @@ void MacroAssembler::InvokeFunction(Register function, ...@@ -2409,7 +2414,8 @@ void MacroAssembler::InvokeFunction(Register function,
DCHECK(function.Is(x1)); DCHECK(function.Is(x1));
// Set up the context. // Set up the context.
Ldr(cp, FieldMemOperand(function, JSFunction::kContextOffset)); LoadTaggedPointerField(cp,
FieldMemOperand(function, JSFunction::kContextOffset));
InvokeFunctionCode(function, no_reg, expected, actual, flag); InvokeFunctionCode(function, no_reg, expected, actual, flag);
} }
...@@ -2697,7 +2703,7 @@ void MacroAssembler::CompareObjectType(Register object, ...@@ -2697,7 +2703,7 @@ void MacroAssembler::CompareObjectType(Register object,
Register map, Register map,
Register type_reg, Register type_reg,
InstanceType type) { InstanceType type) {
Ldr(map, FieldMemOperand(object, HeapObject::kMapOffset)); LoadTaggedPointerField(map, FieldMemOperand(object, HeapObject::kMapOffset));
CompareInstanceType(map, type_reg, type); CompareInstanceType(map, type_reg, type);
} }
...@@ -2738,6 +2744,24 @@ void MacroAssembler::JumpIfNotRoot(const Register& obj, RootIndex index, ...@@ -2738,6 +2744,24 @@ void MacroAssembler::JumpIfNotRoot(const Register& obj, RootIndex index,
B(ne, if_not_equal); B(ne, if_not_equal);
} }
void TurboAssembler::LoadTaggedPointerField(const Register& destination,
const MemOperand& field_operand) {
#ifdef V8_COMPRESS_POINTERS
DecompressTaggedPointer(destination, field_operand);
#else
Ldr(destination, field_operand);
#endif
}
void TurboAssembler::LoadAnyTaggedField(const Register& destination,
const MemOperand& field_operand) {
#ifdef V8_COMPRESS_POINTERS
DecompressAnyTagged(destination, field_operand);
#else
Ldr(destination, field_operand);
#endif
}
void TurboAssembler::DecompressTaggedSigned(const Register& destination, void TurboAssembler::DecompressTaggedSigned(const Register& destination,
const MemOperand& field_operand) { const MemOperand& field_operand) {
RecordComment("[ DecompressTaggedSigned"); RecordComment("[ DecompressTaggedSigned");
...@@ -3188,8 +3212,8 @@ void TurboAssembler::Abort(AbortReason reason) { ...@@ -3188,8 +3212,8 @@ void TurboAssembler::Abort(AbortReason reason) {
} }
void MacroAssembler::LoadNativeContextSlot(int index, Register dst) { void MacroAssembler::LoadNativeContextSlot(int index, Register dst) {
Ldr(dst, NativeContextMemOperand()); LoadTaggedPointerField(dst, NativeContextMemOperand());
Ldr(dst, ContextMemOperand(dst, index)); LoadTaggedPointerField(dst, ContextMemOperand(dst, index));
} }
......
...@@ -1176,7 +1176,16 @@ class V8_EXPORT_PRIVATE TurboAssembler : public TurboAssemblerBase { ...@@ -1176,7 +1176,16 @@ class V8_EXPORT_PRIVATE TurboAssembler : public TurboAssemblerBase {
void ResetSpeculationPoisonRegister(); void ResetSpeculationPoisonRegister();
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
// Pointer compresstion Support // Pointer compression Support
// Loads a field containing a HeapObject and decompresses it if pointer
// compression is enabled.
void LoadTaggedPointerField(const Register& destination,
const MemOperand& field_operand);
// Loads a field containing any tagged value and decompresses it if necessary.
void LoadAnyTaggedField(const Register& destination,
const MemOperand& field_operand);
void DecompressTaggedSigned(const Register& destination, void DecompressTaggedSigned(const Register& destination,
const MemOperand& field_operand); const MemOperand& field_operand);
......
This diff is collapsed.
...@@ -693,12 +693,14 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction( ...@@ -693,12 +693,14 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
// Check the function's context matches the context argument. // Check the function's context matches the context argument.
UseScratchRegisterScope scope(tasm()); UseScratchRegisterScope scope(tasm());
Register temp = scope.AcquireX(); Register temp = scope.AcquireX();
__ Ldr(temp, FieldMemOperand(func, JSFunction::kContextOffset)); __ LoadTaggedPointerField(
temp, FieldMemOperand(func, JSFunction::kContextOffset));
__ cmp(cp, temp); __ cmp(cp, temp);
__ Assert(eq, AbortReason::kWrongFunctionContext); __ Assert(eq, AbortReason::kWrongFunctionContext);
} }
static_assert(kJavaScriptCallCodeStartRegister == x2, "ABI mismatch"); static_assert(kJavaScriptCallCodeStartRegister == x2, "ABI mismatch");
__ Ldr(x2, FieldMemOperand(func, JSFunction::kCodeOffset)); __ LoadTaggedPointerField(x2,
FieldMemOperand(func, JSFunction::kCodeOffset));
__ CallCodeObject(x2); __ CallCodeObject(x2);
RecordCallPosition(instr); RecordCallPosition(instr);
frame_access_state()->ClearSPDelta(); frame_access_state()->ClearSPDelta();
...@@ -2464,8 +2466,9 @@ void CodeGenerator::AssembleConstructFrame() { ...@@ -2464,8 +2466,9 @@ void CodeGenerator::AssembleConstructFrame() {
__ Str(kWasmInstanceRegister, __ Str(kWasmInstanceRegister,
MemOperand(fp, WasmCompiledFrameConstants::kWasmInstanceOffset)); MemOperand(fp, WasmCompiledFrameConstants::kWasmInstanceOffset));
} }
__ Ldr(x2, FieldMemOperand(kWasmInstanceRegister, __ LoadTaggedPointerField(
WasmInstanceObject::kCEntryStubOffset)); x2, FieldMemOperand(kWasmInstanceRegister,
WasmInstanceObject::kCEntryStubOffset));
__ Mov(cp, Smi::zero()); __ Mov(cp, Smi::zero());
__ CallRuntimeWithCEntry(Runtime::kThrowWasmStackOverflow, x2); __ CallRuntimeWithCEntry(Runtime::kThrowWasmStackOverflow, x2);
// We come from WebAssembly, there are no references for the GC. // We come from WebAssembly, there are no references for the GC.
......
...@@ -40,7 +40,8 @@ void DebugCodegen::GenerateFrameDropperTrampoline(MacroAssembler* masm) { ...@@ -40,7 +40,8 @@ void DebugCodegen::GenerateFrameDropperTrampoline(MacroAssembler* masm) {
__ Mov(sp, fp); __ Mov(sp, fp);
__ Pop(fp, lr); // Frame, Return address. __ Pop(fp, lr); // Frame, Return address.
__ Ldr(x0, FieldMemOperand(x1, JSFunction::kSharedFunctionInfoOffset)); __ LoadTaggedPointerField(
x0, FieldMemOperand(x1, JSFunction::kSharedFunctionInfoOffset));
__ Ldrh(x0, __ Ldrh(x0,
FieldMemOperand(x0, SharedFunctionInfo::kFormalParameterCountOffset)); FieldMemOperand(x0, SharedFunctionInfo::kFormalParameterCountOffset));
__ mov(x2, x0); __ mov(x2, x0);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment