// FCLASS returns a 10-bit classification mask with the two highest bits marking NaNs // (signaling and quiet). To detect a NaN, we can compare (either BGE or BGEU, the sign // bit is always clear) the result with the `kFClassNaNMinValue`.
static_assert(kSignalingNaN == 0x100);
static_assert(kQuietNaN == 0x200); static constexpr int32_t kFClassNaNMinValue = 0x100;
// Method register on invoke. staticconst XRegister kArtMethodRegister = A0;
// Helper functions used by codegen as well as intrinsics.
XRegister InputXRegisterOrZero(Location location);
int32_t ReadBarrierMarkEntrypointOffset(Location ref);
class CodeGeneratorRISCV64;
class InvokeRuntimeCallingConvention : public CallingConvention<XRegister, FRegister> { public:
InvokeRuntimeCallingConvention()
: CallingConvention(kRuntimeParameterCoreRegisters,
kRuntimeParameterCoreRegistersLength,
kRuntimeParameterFpuRegisters,
kRuntimeParameterFpuRegistersLength,
kRiscv64PointerSize) {}
private: // Register allocator does not support adjusting frame size, so we cannot provide final locations // of stack arguments for register allocation. We ask the register allocator for any location and // move these arguments to the right place after adjusting the SP when generating the call. constbool for_register_allocation_;
size_t gpr_index_ = 0u;
size_t fpr_index_ = 0u;
size_t stack_offset_ = 0u;
// Sequentially consistent store. Used for volatile fields and intrinsics. // The `instruction` argument is for recording an implicit null check stack map with the // store instruction which may not be the last instruction emitted by `StoreSeqCst()`. void StoreSeqCst(Location value,
XRegister rs1,
int32_t offset,
DataType::Type type,
HInstruction* instruction = nullptr);
// Generate a heap reference load using one register `out`: // // out <- *(out + offset) // // while honoring heap poisoning and/or read barriers (if any). // // Location `maybe_temp` is used when generating a read barrier and // shall be a register in that case; it may be an invalid location // otherwise. void GenerateReferenceLoadOneRegister(HInstruction* instruction,
Location out,
uint32_t offset,
Location maybe_temp,
ReadBarrierOption read_barrier_option); // Generate a heap reference load using two different registers // `out` and `obj`: // // out <- *(obj + offset) // // while honoring heap poisoning and/or read barriers (if any). // // Location `maybe_temp` is used when generating a Baker's (fast // path) read barrier and shall be a register in that case; it may // be an invalid location otherwise. void GenerateReferenceLoadTwoRegisters(HInstruction* instruction,
Location out,
Location obj,
uint32_t offset,
Location maybe_temp,
ReadBarrierOption read_barrier_option);
size_t GetWordSize() const override { // The "word" for the compiler is the core register size (64-bit for riscv64) while the // riscv64 assembler uses "word" for 32-bit values and "double word" for 64-bit values. return kRiscv64DoublewordSize;
}
// Get FP register width in bytes for spilling/restoring in the slow paths. // // Note: In SIMD graphs this should return SIMD register width as all FP and SIMD registers // alias and live SIMD registers are forced to be spilled in full size in the slow paths.
size_t GetSlowPathFPWidth() const override { // Default implementation. return GetCalleePreservedFPWidth();
}
size_t GetSIMDRegisterWidth() const override { // TODO(riscv64): Implement SIMD with the Vector extension. // Note: HLoopOptimization calls this function even for an ISA without SIMD support. return kRiscv64FloatRegSizeInBytes;
};
// Generate code to invoke a runtime entry point. void InvokeRuntime(QuickEntrypointEnum entrypoint,
HInstruction* instruction,
SlowPathCode* slow_path = nullptr) override;
// Generate code to invoke a runtime entry point, but do not record // PC-related information in a stack map. void InvokeRuntimeWithoutRecordingPcInfo(int32_t entry_point_offset,
HInstruction* instruction,
SlowPathCode* slow_path);
// Check if the desired_string_load_kind is supported. If it is, return it, // otherwise return a fall-back kind that should be used instead.
HLoadString::LoadKind GetSupportedLoadStringKind(
HLoadString::LoadKind desired_string_load_kind) override;
// Check if the desired_class_load_kind is supported. If it is, return it, // otherwise return a fall-back kind that should be used instead.
HLoadClass::LoadKind GetSupportedLoadClassKind(
HLoadClass::LoadKind desired_class_load_kind) override;
// Check if the desired_dispatch_info is supported. If it is, return it, // otherwise return a fall-back info that should be used instead.
HInvokeStaticOrDirect::DispatchInfo GetSupportedInvokeStaticOrDirectDispatch( const HInvokeStaticOrDirect::DispatchInfo& desired_dispatch_info, ArtMethod* method) override;
// The PcRelativePatchInfo is used for PC-relative addressing of methods/strings/types, // whether through .data.img.rel.ro, .bss, or directly in the boot image. // // The 20-bit and 12-bit parts of the 32-bit PC-relative offset are patched separately, // necessitating two patches/infos. There can be more than two patches/infos if the // instruction supplying the high part is shared with e.g. a slow path, while the low // part is supplied by separate instructions, e.g.: // auipc r1, high // patch // lwu r2, low(r1) // patch // beqz r2, slow_path // back: // ... // slow_path: // ... // sw r2, low(r1) // patch // j back struct PcRelativePatchInfo : PatchInfo<Riscv64Label> {
PcRelativePatchInfo(const DexFile* dex_file,
uint32_t off_or_idx, const PcRelativePatchInfo* info_high)
: PatchInfo<Riscv64Label>(dex_file, off_or_idx),
pc_insn_label(info_high != nullptr ? &info_high->label : &label) {
DCHECK_IMPLIES(info_high != nullptr, info_high->pc_insn_label == &info_high->label);
}
// Pointer to the info for the high part patch or nullptr if this is the high part patch info. const Riscv64Label* pc_insn_label;
// Create slow path for a Baker read barrier for a GC root load within `instruction`.
SlowPathCodeRISCV64* AddGcRootBakerBarrierBarrierSlowPath(
HInstruction* instruction, Location root, Location temp);
// Emit marking check for a Baker read barrier for a GC root load within `instruction`. void EmitBakerReadBarierMarkingCheck(
SlowPathCodeRISCV64* slow_path, Location root, Location temp);
// Fast path implementation of ReadBarrier::Barrier for a heap // reference field load when Baker's read barriers are used. void GenerateFieldLoadWithBakerReadBarrier(HInstruction* instruction,
Location ref,
XRegister obj,
uint32_t offset,
Location temp, bool needs_null_check); // Fast path implementation of ReadBarrier::Barrier for a heap // reference array load when Baker's read barriers are used. void GenerateArrayLoadWithBakerReadBarrier(HInstruction* instruction,
Location ref,
XRegister obj,
uint32_t data_offset,
Location index,
Location temp, bool needs_null_check); // Factored implementation, used by GenerateFieldLoadWithBakerReadBarrier, // GenerateArrayLoadWithBakerReadBarrier and intrinsics. void GenerateReferenceLoadWithBakerReadBarrier(HInstruction* instruction,
Location ref,
XRegister obj,
uint32_t offset,
Location index,
Location temp, bool needs_null_check);
// Create slow path for a read barrier for a heap reference within `instruction`. // // This is a helper function for GenerateReadBarrierSlow() that has the same // arguments. The creation and adding of the slow path is exposed for intrinsics // that cannot use GenerateReadBarrierSlow() from their own slow paths.
SlowPathCodeRISCV64* AddReadBarrierSlowPath(HInstruction* instruction,
Location out,
Location ref,
Location obj,
uint32_t offset,
Location index);
// Generate a read barrier for a heap reference within `instruction` // using a slow path. // // A read barrier for an object reference read from the heap is // implemented as a call to the artReadBarrierSlow runtime entry // point, which is passed the values in locations `ref`, `obj`, and // `offset`: // // mirror::Object* artReadBarrierSlow(mirror::Object* ref, // mirror::Object* obj, // uint32_t offset); // // The `out` location contains the value returned by // artReadBarrierSlow. // // When `index` is provided (i.e. for array accesses), the offset // value passed to artReadBarrierSlow is adjusted to take `index` // into account. void GenerateReadBarrierSlow(HInstruction* instruction,
Location out,
Location ref,
Location obj,
uint32_t offset,
Location index = Location::NoLocation());
// If read barriers are enabled, generate a read barrier for a heap // reference using a slow path. If heap poisoning is enabled, also // unpoison the reference in `out`. void MaybeGenerateReadBarrierSlow(HInstruction* instruction,
Location out,
Location ref,
Location obj,
uint32_t offset,
Location index = Location::NoLocation());
// Generate a read barrier for a GC root within `instruction` using // a slow path. // // A read barrier for an object reference GC root is implemented as // a call to the artReadBarrierForRootSlow runtime entry point, // which is passed the value in location `root`: // // mirror::Object* artReadBarrierForRootSlow(GcRoot<mirror::Object>* root); // // The `out` location contains the value returned by // artReadBarrierForRootSlow. void GenerateReadBarrierForRootSlow(HInstruction* instruction, Location out, Location root);
// Emit a write barrier if: // A) emit_null_check is false // B) emit_null_check is true, and value is not null. void MaybeMarkGCCard(XRegister object, XRegister value, bool emit_null_check);
// Emit a write barrier unconditionally. void MarkGCCard(XRegister object);
// Crash if the card table is not valid. This check is only emitted for the CC GC. We assert // `(!clean || !self->is_gc_marking)`, since the card table should not be set to clean when the CC // GC is marking for eliminated write barriers. void CheckGCCardIsValid(XRegister object);
// // Heap poisoning. //
// Poison a heap reference contained in `reg`. void PoisonHeapReference(XRegister reg);
// Unpoison a heap reference contained in `reg`. void UnpoisonHeapReference(XRegister reg);
// Poison a heap reference contained in `reg` if heap poisoning is enabled. void MaybePoisonHeapReference(XRegister reg);
// Unpoison a heap reference contained in `reg` if heap poisoning is enabled. void MaybeUnpoisonHeapReference(XRegister reg);
// Labels for each block that will be compiled.
Riscv64Label* block_labels_; // Indexed by block id.
ParallelMoveResolverRISCV64 move_resolver_;
// Deduplication map for 32-bit literals, used for non-patchable boot image addresses.
Uint32ToLiteralMap uint32_literals_; // Deduplication map for 64-bit literals, used for non-patchable method address or method code // address.
Uint64ToLiteralMap uint64_literals_;
// PC-relative method patch info for kBootImageLinkTimePcRelative.
ArenaDeque<PcRelativePatchInfo> boot_image_method_patches_; // PC-relative method patch info for kAppImageRelRo.
ArenaDeque<PcRelativePatchInfo> app_image_method_patches_; // PC-relative method patch info for kBssEntry.
ArenaDeque<PcRelativePatchInfo> method_bss_entry_patches_; // PC-relative type patch info for kBootImageLinkTimePcRelative.
ArenaDeque<PcRelativePatchInfo> boot_image_type_patches_; // PC-relative type patch info for kAppImageRelRo.
ArenaDeque<PcRelativePatchInfo> app_image_type_patches_; // PC-relative type patch info for kBssEntry.
ArenaDeque<PcRelativePatchInfo> type_bss_entry_patches_; // PC-relative public type patch info for kBssEntryPublic.
ArenaDeque<PcRelativePatchInfo> public_type_bss_entry_patches_; // PC-relative package type patch info for kBssEntryPackage.
ArenaDeque<PcRelativePatchInfo> package_type_bss_entry_patches_; // PC-relative String patch info for kBootImageLinkTimePcRelative.
ArenaDeque<PcRelativePatchInfo> boot_image_string_patches_; // PC-relative String patch info for kAppImageRelRo.
ArenaDeque<PcRelativePatchInfo> app_image_string_patches_; // PC-relative String patch info for kBssEntry.
ArenaDeque<PcRelativePatchInfo> string_bss_entry_patches_; // PC-relative method patch info for kBootImageLinkTimePcRelative+kCallCriticalNative.
ArenaDeque<PcRelativePatchInfo> boot_image_jni_entrypoint_patches_; // PC-relative patch info for IntrinsicObjects for the boot image, // and for method/type/string patches for kBootImageRelRo otherwise.
ArenaDeque<PcRelativePatchInfo> boot_image_other_patches_;
// Patches for string root accesses in JIT compiled code.
StringToLiteralMap jit_string_patches_; // Patches for class root accesses in JIT compiled code.
TypeToLiteralMap jit_class_patches_;
};
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.