v8
V8 is Google’s open source high-performance JavaScript and WebAssembly engine, written in C++.
Loading...
Searching...
No Matches
pipeline-data-inl.h
Go to the documentation of this file.
1// Copyright 2024 the V8 project authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef V8_COMPILER_PIPELINE_DATA_INL_H_
6#define V8_COMPILER_PIPELINE_DATA_INL_H_
7
8#include <optional>
9
13#include "src/common/globals.h"
29#include "src/compiler/phase.h"
40
41#if V8_ENABLE_WEBASSEMBLY
43#endif
44
45namespace v8::internal::compiler {
46
48 Tagged<Context> current = info->closure()->context();
49 size_t distance = 0;
50 while (!IsNativeContext(*current)) {
51 if (current->IsModuleContext()) {
52 return Just(OuterContext(
53 info->CanonicalHandle(current, current->GetIsolate()), distance));
54 }
55 current = current->previous();
56 distance++;
57 }
58 return Nothing<OuterContext>();
59}
60
62 public:
63 // For main entry point.
67 : isolate_(isolate),
68 allocator_(isolate->allocator()),
69 info_(info),
80 info_->trace_heap_broker(),
81 info->code_kind())),
85 assembler_options_(AssemblerOptions::Default(isolate)) {
86 PhaseScope scope(pipeline_statistics, "V8.TFInitPipelineData");
89 node_origins_ = info->trace_turbo_json()
91 : nullptr;
92#if V8_ENABLE_WEBASSEMBLY
93 js_wasm_calls_sidetable_ =
95#endif // V8_ENABLE_WEBASSEMBLY
106 info->node_observer()
108 : nullptr;
110 info_->zone());
111 }
112
113#if V8_ENABLE_WEBASSEMBLY
114 // For WebAssembly compile entry point.
121 : isolate_(nullptr),
122 allocator_(wasm_engine->allocator()),
123 info_(info),
129 graph_(mcgraph->graph()),
132 machine_(mcgraph->machine()),
147 }
148#endif // V8_ENABLE_WEBASSEMBLY
149
150 // For CodeStubAssembler and machine graph testing entry point.
152 Isolate* isolate, AccountingAllocator* allocator,
158 : isolate_(isolate),
159 allocator_(allocator),
160 info_(info),
164 graph_(graph),
175 jump_optimization_info_(jump_opt),
178 if (jsgraph) {
184 } else if (graph_) {
194 }
195 }
196
197 // For register allocation testing entry point.
215
217 // Must happen before zones are destroyed.
218 delete code_generator_;
219 code_generator_ = nullptr;
220 DeleteTyper();
225 }
226
229
230 Isolate* isolate() const { return isolate_; }
233 ZoneStats* zone_stats() const { return zone_stats_; }
238 OsrHelper* osr_helper() { return osr_helper_.get(); }
239 std::shared_ptr<OsrHelper> osr_helper_ptr() const { return osr_helper_; }
240
241 bool verify_graph() const { return verify_graph_; }
242 void set_verify_graph(bool value) { verify_graph_ = value; }
243
246 DCHECK(code_.is_null());
247 code_ = code;
248 }
249
251
252 // RawMachineAssembler generally produces graphs which cannot be verified.
254
256 TFGraph* graph() const { return graph_; }
257 void set_graph(TFGraph* graph) { graph_ = graph; }
258 template <typename T>
288 // Call `DeleteGraphZone` to reset all pointers. The actual zone is not
289 // released because we moved it away.
291 return temp;
292 }
305 JSGraph* jsgraph() const { return jsgraph_; }
306 MachineGraph* mcgraph() const { return mcgraph_; }
313
314 JSHeapBroker* broker() const { return broker_.get(); }
315 std::shared_ptr<JSHeapBroker> broker_ptr() { return broker_; }
316
317 Schedule* schedule() const { return schedule_; }
322 void reset_schedule() { schedule_ = nullptr; }
323
327
329 Zone* codegen_zone() const { return codegen_zone_; }
331 Frame* frame() const { return frame_; }
332
334
338
339 std::string const& source_position_output() const {
341 }
345
349
351 return assembler_options_;
352 }
353
355 if (info()->function_context_specializing()) {
356 DCHECK(info()->has_context());
358 info()->CanonicalHandle(info()->context(), isolate()), 0));
359 } else {
361 }
362 }
363
367
379 }
380
382#if V8_ENABLE_WEBASSEMBLY
383 if (info_->IsWasm() || info_->IsWasmBuiltin()) {
385 }
386#endif // V8_ENABLE_WEBASSEMBLY
387 return isolate_->GetCodeTracer();
388 }
389
392 typer_ =
393 new Typer(broker(), typer_flags_, graph(), &info()->tick_counter());
394 return typer_;
395 }
396
399 typer_flags_ |= flag;
400 }
401
402 void DeleteTyper() {
403 delete typer_;
404 typer_ = nullptr;
405 }
406
408#ifdef V8_ENABLE_WEBASSEMBLY
409 js_wasm_calls_sidetable_ = nullptr;
410#endif // V8_ENABLE_WEBASSEMBLY
411 graph_ = nullptr;
412 source_positions_ = nullptr;
413 node_origins_ = nullptr;
414 simplified_ = nullptr;
415 machine_ = nullptr;
416 common_ = nullptr;
417 javascript_ = nullptr;
418 jsgraph_ = nullptr;
419 mcgraph_ = nullptr;
420 schedule_ = nullptr;
422 }
423
425 if (instruction_zone_ == nullptr) return;
427 instruction_zone_ = nullptr;
428 sequence_ = nullptr;
429 }
430
432 if (codegen_zone_ == nullptr) return;
434 codegen_zone_ = nullptr;
435 dependencies_ = nullptr;
436 broker_.reset();
437 broker_ = nullptr;
438 frame_ = nullptr;
439 }
440
447
448 void InitializeInstructionSequence(const CallDescriptor* call_descriptor) {
450 InstructionBlocks* instruction_blocks =
452 schedule());
454 isolate(), instruction_zone(), instruction_blocks);
455 if (call_descriptor && call_descriptor->RequiresFrameAsIncoming()) {
456 sequence_->instruction_blocks()[0]->mark_needs_frame();
457 } else {
458 DCHECK(call_descriptor->CalleeSavedFPRegisters().is_empty());
459 }
460 }
461
462 void InitializeFrameData(CallDescriptor* call_descriptor) {
464 int fixed_frame_size = 0;
465 if (call_descriptor != nullptr) {
466 fixed_frame_size =
467 call_descriptor->CalculateFixedFrameSize(info()->code_kind());
468 }
469 frame_ = codegen_zone()->New<Frame>(fixed_frame_size, codegen_zone());
471 }
472
481
484 osr_helper_ = std::make_shared<OsrHelper>(info());
485 }
486
491
493
496#if V8_ENABLE_WEBASSEMBLY
498 this->info()->IsWasm() || this->info()->IsWasmBuiltin();
499#endif
500 std::optional<OsrHelper> osr_helper;
507 v8_flags.trace_turbo_stack_accesses ? debug_name_.get() : nullptr);
508 }
509
510 void BeginPhaseKind(const char* phase_kind_name) {
511 if (pipeline_statistics() != nullptr) {
512 pipeline_statistics()->BeginPhaseKind(phase_kind_name);
513 }
514 }
515
517 if (pipeline_statistics() != nullptr) {
519 }
520 }
521
522 const char* debug_name() const { return debug_name_.get(); }
523
528
529 // RuntimeCallStats that is only available during job execution but not
530 // finalization.
531 // TODO(delphick): Currently even during execution this can be nullptr, due to
532 // JSToWasmWrapperCompilationUnit::Execute. Once a table can be extracted
533 // there, this method can DCHECK that it is never nullptr.
538
539#if V8_ENABLE_WEBASSEMBLY
540 bool has_js_wasm_calls() const {
541 return wasm_module_for_inlining_ != nullptr;
542 }
543 const wasm::WasmModule* wasm_module_for_inlining() const {
544 return wasm_module_for_inlining_;
545 }
546 void set_wasm_module_for_inlining(const wasm::WasmModule* module) {
547 // We may only inline Wasm functions from at most one module, see below.
548 DCHECK_NULL(wasm_module_for_inlining_);
549 wasm_module_for_inlining_ = module;
550 }
552 return js_wasm_calls_sidetable_;
553 }
554#endif // V8_ENABLE_WEBASSEMBLY
555
556 private:
558#if V8_ENABLE_WEBASSEMBLY
559 // The wasm module to be used for inlining wasm functions into JS.
560 // The first module wins and inlining of different modules into the same
561 // JS function is not supported. This is necessary because the wasm
562 // instructions use module-specific (non-canonicalized) type indices.
563 // TODO(353475584): Long-term we might want to lift this restriction, i.e.,
564 // support inlining Wasm functions from different Wasm modules in the
565 // Turboshaft implementation to avoid a surprising performance cliff.
566 const wasm::WasmModule* wasm_module_for_inlining_ = nullptr;
567 // Sidetable for storing/passing information about the to-be-inlined calls to
568 // Wasm functions through the JS Turbofan frontend to the Turboshaft backend.
569 // This should go away once we not only inline the Wasm body in Turboshaft but
570 // also the JS-to-Wasm wrapper (which is currently inlined in Turbofan still).
571 // See https://crbug.com/353475584.
572 JsWasmCallsSidetable* js_wasm_calls_sidetable_ = nullptr;
573#endif // V8_ENABLE_WEBASSEMBLY
576 std::unique_ptr<char[]> debug_name_;
580 bool verify_graph_ = false;
582 std::shared_ptr<OsrHelper> osr_helper_;
585 Typer* typer_ = nullptr;
587
588 // All objects in the following group of fields are allocated in graph_zone_.
589 // They are all set to nullptr when the graph_zone_ is destroyed.
591 TFGraph* graph_ = nullptr;
598 JSGraph* jsgraph_ = nullptr;
600 Schedule* schedule_ = nullptr;
602 std::unique_ptr<turboshaft::PipelineData> ts_data_;
603
604 // All objects in the following group of fields are allocated in
605 // instruction_zone_. They are all set to nullptr when the instruction_zone_
606 // is destroyed.
610
611 // All objects in the following group of fields are allocated in
612 // codegen_zone_. They are all set to nullptr when the codegen_zone_
613 // is destroyed.
617 std::shared_ptr<JSHeapBroker> broker_;
618 Frame* frame_ = nullptr;
619
620 // All objects in the following group of fields are allocated in
621 // register_allocation_zone_. They are all set to nullptr when the zone is
622 // destroyed.
626
627 // Source position output for --trace-turbo.
629
633
634 // The maximal combined height of all inlined frames in their unoptimized
635 // state, and the maximal number of arguments pushed during function calls.
636 // Calculated during instruction selection, applied during code generation.
639
642};
643
644} // namespace v8::internal::compiler
645
646#endif // V8_COMPILER_PIPELINE_DATA_INL_H_
CodeTracer * GetCodeTracer()
Definition isolate.cc:6124
static constexpr MachineRepresentation PointerRepresentation()
constexpr bool is_empty() const
T * New(Args &&... args)
Definition zone.h:114
int CalculateFixedFrameSize(CodeKind code_kind) const
Definition linkage.cc:204
DoubleRegList CalleeSavedFPRegisters() const
Definition linkage.h:303
static MachineOperatorBuilder::AlignmentRequirements AlignmentRequirements()
static MachineOperatorBuilder::Flags SupportedMachineOperatorFlags()
static InstructionBlocks * InstructionBlocksFor(Zone *zone, const Schedule *schedule)
const InstructionBlocks & instruction_blocks() const
JSOperatorBuilder * javascript() const
Definition js-graph.h:104
SimplifiedOperatorBuilder * simplified() const
Definition js-graph.h:105
CommonOperatorBuilder * common() const
MachineOperatorBuilder * machine() const
V8_EXPORT_PRIVATE void SetupFrame(Frame *frame)
Definition osr.cc:21
turboshaft::ZoneWithNamePointer< T, kGraphZoneName > GraphZonePointer
void set_node_origins(NodeOriginTable *node_origins)
RegisterAllocationData * register_allocation_data() const
TurbofanPipelineStatistics * pipeline_statistics()
TFPipelineData(const TFPipelineData &)=delete
void InitializeInstructionSequence(const CallDescriptor *call_descriptor)
ObserveNodeManager * observe_node_manager() const
Maybe< OuterContext > specialization_context() const
AccountingAllocator * allocator() const
MachineOperatorBuilder * machine() const
turboshaft::ZoneWithName< kGraphZoneName > ReleaseGraphZone()
void InitializeFrameData(CallDescriptor *call_descriptor)
std::shared_ptr< OsrHelper > osr_helper_
OptimizedCompilationInfo *const info_
void set_runtime_call_stats(RuntimeCallStats *stats)
RegisterAllocationData * register_allocation_data_
SourcePositionTable * source_positions() const
TFPipelineData(ZoneStats *zone_stats, Isolate *isolate, OptimizedCompilationInfo *info, TurbofanPipelineStatistics *pipeline_statistics)
CommonOperatorBuilder * common() const
turboshaft::ZoneWithName< kGraphZoneName > graph_zone_
OptimizedCompilationInfo * info() const
MaybeIndirectHandle< Code > code()
std::unique_ptr< turboshaft::PipelineData > ts_data_
TFPipelineData(ZoneStats *zone_stats, OptimizedCompilationInfo *info, Isolate *isolate, AccountingAllocator *allocator, TFGraph *graph, JSGraph *jsgraph, Schedule *schedule, SourcePositionTable *source_positions, NodeOriginTable *node_origins, JumpOptimizationInfo *jump_opt, const AssemblerOptions &assembler_options, const ProfileDataFromFile *profile_data)
DirectHandle< JSGlobalObject > global_object() const
void set_source_position_output(std::string const &source_position_output)
void InitializeWithGraphZone(turboshaft::ZoneWithName< kGraphZoneName > graph_zone, GraphZonePointer< SourcePositionTable > source_positions, GraphZonePointer< NodeOriginTable > node_origins, size_t node_count_hint=0)
const AssemblerOptions & assembler_options() const
void set_code(MaybeIndirectHandle< Code > code)
JumpOptimizationInfo * jump_optimization_info() const
const ProfileDataFromFile * profile_data_
DirectHandle< NativeContext > native_context() const
std::shared_ptr< JSHeapBroker > broker_
SimplifiedOperatorBuilder * simplified() const
void BeginPhaseKind(const char *phase_kind_name)
SimplifiedOperatorBuilder * simplified_
JSOperatorBuilder * javascript() const
TurbofanPipelineStatistics * pipeline_statistics_
void set_profile_data(const ProfileDataFromFile *profile_data)
void set_source_positions(SourcePositionTable *source_positions)
std::shared_ptr< OsrHelper > osr_helper_ptr() const
TFPipelineData(ZoneStats *zone_stats, OptimizedCompilationInfo *info, Isolate *isolate, InstructionSequence *sequence)
InstructionSequence * sequence() const
const ProfileDataFromFile * profile_data() const
CompilationDependencies * dependencies() const
std::shared_ptr< JSHeapBroker > broker_ptr()
void InitializeRegisterAllocationData(const RegisterConfiguration *config, CallDescriptor *call_descriptor)
TFPipelineData & operator=(const TFPipelineData &)=delete
RuntimeCallStats * runtime_call_stats() const
std::string const & source_position_output() const
ZoneWithNamePointer< T, Name > New(Args &&... args)
JsWasmCallsSidetable * js_wasm_calls_sidetable
Linkage * linkage
TNode< Context > context
int position
Definition liveedit.cc:290
base::Vector< const char > GetDebugName(Zone *zone, const wasm::WasmModule *module, const wasm::WireBytesStorage *wire_bytes, int index)
constexpr char kInstructionZoneName[]
Definition phase.h:40
constexpr char kRegisterAllocationZoneName[]
Definition phase.h:41
constexpr char kGraphZoneName[]
Definition phase.h:39
ZoneMap< NodeId, const JSWasmCallParameters * > JsWasmCallsSidetable
Definition js-inlining.h:28
OptionalContextRef GetModuleContext(JSHeapBroker *broker, Node *node, Maybe< OuterContext > maybe_context)
constexpr char kCodegenZoneName[]
Definition phase.h:38
WasmEngine * GetWasmEngine()
constexpr int kNoSourcePosition
Definition globals.h:850
V8_INLINE DirectHandle< T > direct_handle(Tagged< T > object, Isolate *isolate)
static constexpr bool kCompressGraphZone
Definition globals.h:525
V8_EXPORT_PRIVATE FlagValues v8_flags
return value
Definition map-inl.h:893
Maybe< T > Nothing()
Definition v8-maybe.h:112
Maybe< T > Just(const T &t)
Definition v8-maybe.h:117
#define DCHECK_NULL(val)
Definition logging.h:491
#define DCHECK(condition)
Definition logging.h:482
#define DCHECK_EQ(v1, v2)
Definition logging.h:485