#include "src/compiler/backend/code-generator.h"
#include <optional>
#include "src/base/bounds.h"
#include "src/base/iterator.h"
#include "src/codegen/assembler-inl.h"
#include "src/codegen/macro-assembler-inl.h"
#include "src/codegen/optimized-compilation-info.h"
#include "src/compiler/backend/code-generator-impl.h"
#include "src/compiler/globals.h"
#include "src/compiler/linkage.h"
#include "src/compiler/pipeline.h"
#include "src/deoptimizer/translated-state.h"
#include "src/diagnostics/eh-frame.h"
#include "src/execution/frames.h"
#include "src/logging/counters.h"
#include "src/logging/log.h"
#include "src/objects/code-kind.h"
#include "src/objects/smi.h"
#include "src/utils/address-map.h"
#include "src/utils/utils.h"
#if V8_ENABLE_WEBASSEMBLY
#include "src/wasm/wasm-deopt-data.h"
#endif
namespace v8 {
namespace internal {
namespace compiler {
class CodeGenerator::JumpTable final : public ZoneObject { … };
CodeGenerator::CodeGenerator(Zone* codegen_zone, Frame* frame, Linkage* linkage,
InstructionSequence* instructions,
OptimizedCompilationInfo* info, Isolate* isolate,
std::optional<OsrHelper> osr_helper,
int start_source_position,
JumpOptimizationInfo* jump_opt,
const AssemblerOptions& options, Builtin builtin,
size_t max_unoptimized_frame_height,
size_t max_pushed_argument_count,
const char* debug_name)
: … { … }
void CodeGenerator::RecordProtectedInstruction(uint32_t instr_offset) { … }
void CodeGenerator::CreateFrameAccessState(Frame* frame) { … }
bool CodeGenerator::ShouldApplyOffsetToStackCheck(Instruction* instr,
uint32_t* offset) { … }
uint32_t CodeGenerator::GetStackCheckOffset() { … }
CodeGenerator::CodeGenResult CodeGenerator::AssembleDeoptimizerCall(
DeoptimizationExit* exit) { … }
void CodeGenerator::MaybeEmitOutOfLineConstantPool() { … }
void CodeGenerator::AssembleCode() { … }
#ifndef V8_TARGET_ARCH_X64
void CodeGenerator::AssembleArchBinarySearchSwitchRange(
Register input, RpoNumber def_block, std::pair<int32_t, Label*>* begin,
std::pair<int32_t, Label*>* end) {
if (end - begin < kBinarySearchSwitchMinimalCases) {
while (begin != end) {
masm()->JumpIfEqual(input, begin->first, begin->second);
++begin;
}
AssembleArchJumpRegardlessOfAssemblyOrder(def_block);
return;
}
auto middle = begin + (end - begin) / 2;
Label less_label;
masm()->JumpIfLessThan(input, middle->first, &less_label);
AssembleArchBinarySearchSwitchRange(input, def_block, middle, end);
masm()->bind(&less_label);
AssembleArchBinarySearchSwitchRange(input, def_block, begin, middle);
}
#endif
void CodeGenerator::AssembleArchJump(RpoNumber target) { … }
base::OwnedVector<uint8_t> CodeGenerator::GetSourcePositionTable() { … }
base::OwnedVector<uint8_t> CodeGenerator::GetProtectedInstructionsData() { … }
MaybeHandle<Code> CodeGenerator::FinalizeCode() { … }
bool CodeGenerator::IsNextInAssemblyOrder(RpoNumber block) const { … }
void CodeGenerator::RecordSafepoint(ReferenceMap* references, int pc_offset) { … }
bool CodeGenerator::IsMaterializableFromRoot(Handle<HeapObject> object,
RootIndex* index_return) { … }
CodeGenerator::CodeGenResult CodeGenerator::AssembleBlock(
const InstructionBlock* block) { … }
bool CodeGenerator::IsValidPush(InstructionOperand source,
CodeGenerator::PushTypeFlags push_type) { … }
void CodeGenerator::GetPushCompatibleMoves(Instruction* instr,
PushTypeFlags push_type,
ZoneVector<MoveOperands*>* pushes) { … }
CodeGenerator::MoveType::Type CodeGenerator::MoveType::InferMove(
InstructionOperand* source, InstructionOperand* destination) { … }
CodeGenerator::MoveType::Type CodeGenerator::MoveType::InferSwap(
InstructionOperand* source, InstructionOperand* destination) { … }
RpoNumber CodeGenerator::ComputeBranchInfo(BranchInfo* branch,
FlagsCondition condition,
Instruction* instr) { … }
CodeGenerator::CodeGenResult CodeGenerator::AssembleInstruction(
int instruction_index, const InstructionBlock* block) { … }
void CodeGenerator::AssembleSourcePosition(Instruction* instr) { … }
void CodeGenerator::AssembleSourcePosition(SourcePosition source_position) { … }
bool CodeGenerator::GetSlotAboveSPBeforeTailCall(Instruction* instr,
int* slot) { … }
StubCallMode CodeGenerator::DetermineStubCallMode() const { … }
void CodeGenerator::AssembleGaps(Instruction* instr) { … }
namespace {
Handle<TrustedPodArray<InliningPosition>> CreateInliningPositions(
OptimizedCompilationInfo* info, Isolate* isolate) { … }
}
Handle<DeoptimizationData> CodeGenerator::GenerateDeoptimizationData() { … }
#if V8_ENABLE_WEBASSEMBLY
base::OwnedVector<uint8_t> CodeGenerator::GenerateWasmDeoptimizationData() { … }
#endif
Label* CodeGenerator::AddJumpTable(Label** targets, size_t target_count) { … }
#ifndef V8_TARGET_ARCH_X64
void CodeGenerator::AssemblePlaceHolderForLazyDeopt(Instruction* instr) {
UNREACHABLE();
}
#endif
void CodeGenerator::RecordCallPosition(Instruction* instr) { … }
void CodeGenerator::RecordDeoptInfo(Instruction* instr, int pc_offset) { … }
int CodeGenerator::DefineDeoptimizationLiteral(DeoptimizationLiteral literal) { … }
DeoptimizationEntry const& CodeGenerator::GetDeoptimizationEntry(
Instruction* instr, size_t frame_state_offset) { … }
void CodeGenerator::TranslateStateValueDescriptor(
StateValueDescriptor* desc, StateValueList* nested,
InstructionOperandIterator* iter) { … }
void CodeGenerator::TranslateFrameStateDescriptorOperands(
FrameStateDescriptor* desc, InstructionOperandIterator* iter) { … }
void CodeGenerator::BuildTranslationForFrameStateDescriptor(
FrameStateDescriptor* descriptor, InstructionOperandIterator* iter,
OutputFrameStateCombine state_combine) { … }
DeoptimizationExit* CodeGenerator::BuildTranslation(
Instruction* instr, int pc_offset, size_t frame_state_offset,
size_t immediate_args_count, OutputFrameStateCombine state_combine) { … }
void CodeGenerator::AddTranslationForOperand(Instruction* instr,
InstructionOperand* op,
MachineType type) { … }
DeoptimizationExit* CodeGenerator::AddDeoptimizationExit(
Instruction* instr, size_t frame_state_offset,
size_t immediate_args_count) { … }
OutOfLineCode::OutOfLineCode(CodeGenerator* gen)
: … { … }
OutOfLineCode::~OutOfLineCode() = default;
}
}
}