43#define TRACE_COMPILE(...)                                 \ 
   45    if (v8_flags.trace_wasm_compiler) PrintF(__VA_ARGS__); \ 
 
   48#define TRACE_STREAMING(...)                                \ 
   50    if (v8_flags.trace_wasm_streaming) PrintF(__VA_ARGS__); \ 
 
   53#define TRACE_LAZY(...)                                            \ 
   55    if (v8_flags.trace_wasm_lazy_compilation) PrintF(__VA_ARGS__); \ 
 
   62enum class CompileStrategy : uint8_t {
 
   82class CompilationStateImpl;
 
   83class CompilationUnitBuilder;
 
   87  explicit BackgroundCompileScope(std::weak_ptr<NativeModule> native_module)
 
   90  NativeModule* native_module()
 const {
 
   94  inline CompilationStateImpl* compilation_state() 
const;
 
   96  bool cancelled() 
const;
 
  103enum CompilationTier { 
kBaseline = 0, kTopTier = 1, kNumTiers = kTopTier + 1 };
 
  108class CompilationUnitQueues {
 
  112    bool ShouldPublish(
int num_processed_units) 
const;
 
  115  explicit CompilationUnitQueues(
int num_imported_functions,
 
  116                                 int num_declared_functions)
 
  120    queues_.emplace_back(std::make_unique<QueueImpl>(0));
 
  122#if !defined(__cpp_lib_atomic_value_initialization) || \ 
  123    __cpp_lib_atomic_value_initialization < 201911L 
  124    for (
auto& atomic_counter : num_units_) {
 
  125      std::atomic_init(&atomic_counter, 
size_t{0});
 
  130        std::make_unique<std::atomic<bool>[]>(num_declared_functions);
 
  132#if !defined(__cpp_lib_atomic_value_initialization) || \ 
  133    __cpp_lib_atomic_value_initialization < 201911L 
  134    for (
int i = 0; 
i < num_declared_functions; 
i++) {
 
  140  Queue* GetQueueForTask(
int task_id) {
 
  141    int required_queues = task_id + 1;
 
  151    int num_queues = 
static_cast<int>(
queues_.size());
 
  152    while (num_queues < required_queues) {
 
  153      int steal_from = num_queues + 1;
 
  154      queues_.emplace_back(std::make_unique<QueueImpl>(steal_from));
 
  167    int min = std::max(10, units_per_thread / 8);
 
  169    for (
auto& queue : queues_) {
 
  171      int limit = min + (min * queue_id / num_queues);
 
  172      queue->publish_limit.store(limit, std::memory_order_relaxed);
 
  179  std::optional<WasmCompilationUnit> GetNextUnit(Queue* queue,
 
  180                                                 CompilationTier tier) {
 
  181    DCHECK_LT(tier, CompilationTier::kNumTiers);
 
  182    if (
auto unit = GetNextUnitOfTier(queue, tier)) {
 
  183      [[maybe_unused]] 
size_t old_units_count =
 
  184          num_units_[tier].fetch_sub(1, std::memory_order_relaxed);
 
  191  void AddUnits(base::Vector<WasmCompilationUnit> baseline_units,
 
  192                base::Vector<WasmCompilationUnit> top_tier_units,
 
  194    DCHECK_LT(0, baseline_units.size() + top_tier_units.size());
 
  202          queue_to_add, next_task_id(queue_to_add, 
queues_.size()),
 
  203          std::memory_order_relaxed)) {
 
  206      queue = 
queues_[queue_to_add].get();
 
  210    std::optional<base::MutexGuard> big_units_guard;
 
  212         {std::make_pair(CompilationTier::kBaseline, baseline_units),
 
  213          std::make_pair(CompilationTier::kTopTier, top_tier_units)}) {
 
  214      int tier = pair.first;
 
  215      base::Vector<WasmCompilationUnit> 
units = pair.second;
 
  216      if (
units.empty()) 
continue;
 
  219        size_t func_size = 
module->functions[unit.func_index()].code.length();
 
  221          queue->units[tier].push_back(
unit);
 
  223          if (!big_units_guard) {
 
  227                                                 std::memory_order_relaxed);
 
  234  void AddTopTierPriorityUnit(WasmCompilationUnit 
unit, 
size_t priority) {
 
  247        queue_to_add, next_task_id(queue_to_add, 
queues_.size()),
 
  248        std::memory_order_relaxed)) {
 
  253      auto* queue = 
queues_[queue_to_add].get();
 
  257      num_units_[CompilationTier::kTopTier].fetch_add(
 
  258          1, std::memory_order_relaxed);
 
  265  size_t GetSizeForTier(CompilationTier tier)
 const {
 
  266    DCHECK_LT(tier, CompilationTier::kNumTiers);
 
  267    return num_units_[tier].load(std::memory_order_relaxed);
 
  270  void AllowAnotherTopTierJob(uint32_t func_index) {
 
  272        false, std::memory_order_relaxed);
 
  275  size_t EstimateCurrentMemoryConsumption() 
const;
 
  289    bool operator<(
const BigUnit& other)
 const {
 
  294  struct TopTierPriorityUnit {
 
  295    TopTierPriorityUnit(
int priority, WasmCompilationUnit unit)
 
  299    WasmCompilationUnit 
unit;
 
  301    bool operator<(
const TopTierPriorityUnit& other)
 const {
 
  306  struct BigUnitsQueue {
 
  308#if !defined(__cpp_lib_atomic_value_initialization) || \ 
  309    __cpp_lib_atomic_value_initialization < 201911L 
  310      for (
auto& atomic : has_units) std::atomic_init(&atomic, 
false);
 
  317    std::atomic<bool> 
has_units[CompilationTier::kNumTiers];
 
  320    std::priority_queue<BigUnit> 
units[CompilationTier::kNumTiers];
 
  323  struct QueueImpl : 
public Queue {
 
  336    std::vector<WasmCompilationUnit> 
units[CompilationTier::kNumTiers];
 
  341  int next_task_id(
int task_id, 
size_t num_queues)
 const {
 
  342    int next = task_id + 1;
 
  343    return next == 
static_cast<int>(num_queues) ? 0 : next;
 
  346  std::optional<WasmCompilationUnit> GetNextUnitOfTier(Queue* public_queue,
 
  348    QueueImpl* queue = 
static_cast<QueueImpl*
>(public_queue);
 
  351    if (tier == CompilationTier::kTopTier) {
 
  352      if (
auto unit = GetTopTierPriorityUnit(queue)) {
 
  358    if (
auto unit = GetBigUnitOfTier(tier)) 
return unit;
 
  365      if (!queue->units[tier].empty()) {
 
  366        auto unit = queue->units[tier].back();
 
  367        queue->units[tier].pop_back();
 
  370      steal_task_id = queue->next_steal_task_id;
 
  377      for (
size_t steal_trials = 0; steal_trials < 
queues_.size();
 
  378           ++steal_trials, ++steal_task_id) {
 
  379        if (steal_task_id >= 
static_cast<int>(
queues_.size())) {
 
  382        if (
auto unit = StealUnitsAndGetFirst(queue, steal_task_id, tier)) {
 
  392  std::optional<WasmCompilationUnit> GetBigUnitOfTier(
int tier) {
 
  407  std::optional<WasmCompilationUnit> GetTopTierPriorityUnit(QueueImpl* queue) {
 
  416      while (!queue->top_tier_priority_units.empty()) {
 
  417        auto unit = queue->top_tier_priority_units.top().unit;
 
  418        queue->top_tier_priority_units.pop();
 
  422                 .exchange(
true, std::memory_order_relaxed)) {
 
  425        num_units_[CompilationTier::kTopTier].fetch_sub(
 
  426            1, std::memory_order_relaxed);
 
  428      steal_task_id = queue->next_steal_task_id;
 
  435      for (
size_t steal_trials = 0; steal_trials < 
queues_.size();
 
  436           ++steal_trials, ++steal_task_id) {
 
  437        if (steal_task_id >= 
static_cast<int>(
queues_.size())) {
 
  440        if (
auto unit = StealTopTierPriorityUnit(queue, steal_task_id)) {
 
  453  std::optional<WasmCompilationUnit> StealUnitsAndGetFirst(
 
  454      QueueImpl* queue, 
int steal_from_task_id, 
int wanted_tier) {
 
  455    auto* steal_queue = 
queues_[steal_from_task_id].get();
 
  457    if (steal_queue == queue) 
return {};
 
  458    std::vector<WasmCompilationUnit> stolen;
 
  459    std::optional<WasmCompilationUnit> returned_unit;
 
  462      auto* steal_from_vector = &steal_queue->units[wanted_tier];
 
  463      if (steal_from_vector->empty()) 
return {};
 
  464      size_t remaining = steal_from_vector->size() / 2;
 
  465      auto steal_begin = steal_from_vector->begin() + remaining;
 
  466      returned_unit = *steal_begin;
 
  467      stolen.assign(steal_begin + 1, steal_from_vector->end());
 
  468      steal_from_vector->erase(steal_begin, steal_from_vector->end());
 
  471    auto* target_queue = &queue->units[wanted_tier];
 
  472    target_queue->insert(target_queue->end(), stolen.begin(), stolen.end());
 
  473    queue->next_steal_task_id = steal_from_task_id + 1;
 
  474    return returned_unit;
 
  480  std::optional<WasmCompilationUnit> StealTopTierPriorityUnit(
 
  481      QueueImpl* queue, 
int steal_from_task_id) {
 
  482    auto* steal_queue = 
queues_[steal_from_task_id].get();
 
  484    if (steal_queue == queue) 
return {};
 
  485    std::optional<WasmCompilationUnit> returned_unit;
 
  489        if (steal_queue->top_tier_priority_units.empty()) 
return {};
 
  491        auto unit = steal_queue->top_tier_priority_units.top().unit;
 
  492        steal_queue->top_tier_priority_units.pop();
 
  496                 .exchange(
true, std::memory_order_relaxed)) {
 
  497          returned_unit = 
unit;
 
  500        num_units_[CompilationTier::kTopTier].fetch_sub(
 
  501            1, std::memory_order_relaxed);
 
  505    queue->next_steal_task_id = steal_from_task_id + 1;
 
  506    return returned_unit;
 
  510    DCHECK_LE(num_imported_functions_, func_index);
 
  511    DCHECK_LT(func_index, num_imported_functions_ + num_declared_functions_);
 
  517  std::vector<std::unique_ptr<QueueImpl>> 
queues_;
 
  530size_t CompilationUnitQueues::EstimateCurrentMemoryConsumption()
 const {
 
  540    for (
const auto& q : 
queues_) {
 
  541      base::MutexGuard guard(&q->mutex);
 
  543      result += q->top_tier_priority_units.size() * 
sizeof(TopTierPriorityUnit);
 
  556bool CompilationUnitQueues::Queue::ShouldPublish(
 
  557    int num_processed_units)
 const {
 
  558  auto* queue = 
static_cast<const QueueImpl*
>(
this);
 
  559  return num_processed_units >=
 
  560         queue->publish_limit.load(std::memory_order_relaxed);
 
  568class CompilationStateImpl {
 
  570  CompilationStateImpl(
const std::shared_ptr<NativeModule>& native_module,
 
  571                       std::shared_ptr<Counters> async_counters,
 
  572                       WasmDetectedFeatures detected_features);
 
  573  ~CompilationStateImpl() {
 
  584  void InitCompileJob();
 
  589  enum CancellationPolicy { kCancelUnconditionally, kCancelInitialCompilation };
 
  590  void CancelCompilation(CancellationPolicy);
 
  592  bool cancelled() 
const;
 
  596  void ApplyCompilationHintToInitialProgress(
const WasmCompilationHint& hint,
 
  601  void ApplyPgoInfoToInitialProgress(ProfileInformation* pgo_info);
 
  605  void ApplyPgoInfoLate(ProfileInformation* pgo_info);
 
  610  void InitializeCompilationProgress(ProfileInformation* pgo_info);
 
  612  void InitializeCompilationProgressAfterDeserialization(
 
  613      base::Vector<const int> lazy_functions,
 
  614      base::Vector<const int> eager_functions);
 
  618  void InitializeCompilationUnits(
 
  619      std::unique_ptr<CompilationUnitBuilder> builder);
 
  624  void AddCompilationUnit(CompilationUnitBuilder* builder, 
int func_index);
 
  629  void AddCallback(std::unique_ptr<CompilationEventCallback> 
callback);
 
  632  void CommitCompilationUnits(base::Vector<WasmCompilationUnit> baseline_units,
 
  633                              base::Vector<WasmCompilationUnit> top_tier_units);
 
  634  void CommitTopTierCompilationUnit(WasmCompilationUnit);
 
  635  void AddTopTierPriorityCompilationUnit(WasmCompilationUnit, 
size_t);
 
  637  CompilationUnitQueues::Queue* GetQueueForCompileTask(
int task_id);
 
  639  std::optional<WasmCompilationUnit> GetNextCompilationUnit(
 
  640      CompilationUnitQueues::Queue*, CompilationTier tier);
 
  642  void OnFinishedUnits(base::Vector<WasmCode*>);
 
  644  void OnCompilationStopped(WasmDetectedFeatures detected);
 
  645  void SchedulePublishCompilationResults(
 
  646      std::vector<UnpublishedWasmCode> unpublished_code, CompilationTier tier);
 
  648  WasmDetectedFeatures detected_features()
 const {
 
  655      UpdateDetectedFeatures(WasmDetectedFeatures);
 
  657  size_t NumOutstandingCompilations(CompilationTier tier) 
const;
 
  661  void WaitForCompilationEvent(CompilationEvent event);
 
  663  void TierUpAllFunctions();
 
  665  void AllowAnotherTopTierJob(uint32_t func_index) {
 
  669    TypeFeedbackStorage* feedback = &
native_module_->module()->type_feedback;
 
  670    base::MutexGuard mutex_guard(&feedback->mutex);
 
  671    feedback->feedback_for_function[func_index].tierup_priority = 0;
 
  674  void AllowAnotherTopTierJobForAllFunctions() {
 
  676    uint32_t fn_start = 
module->num_imported_functions;
 
  677    uint32_t fn_end = fn_start + module->num_declared_functions;
 
  678    base::MutexGuard mutex_guard(&module->type_feedback.mutex);
 
  679    std::unordered_map<uint32_t, FunctionTypeFeedback>& feedback_map =
 
  680        module->type_feedback.feedback_for_function;
 
  681    for (uint32_t 
i = fn_start; 
i < fn_end; 
i++) {
 
  685      if (
auto it = feedback_map.find(
i); it != feedback_map.end()) {
 
  686        it->second.tierup_priority = 0;
 
  691  bool failed()
 const {
 
  695  bool baseline_compilation_finished()
 const {
 
  702  void SetWireBytesStorage(
 
  703      std::shared_ptr<WireBytesStorage> wire_bytes_storage) {
 
  704    base::MutexGuard guard(&
mutex_);
 
  708  std::shared_ptr<WireBytesStorage> GetWireBytesStorage()
 const {
 
  709    base::MutexGuard guard(&
mutex_);
 
  714  void set_compilation_id(
int compilation_id) {
 
  719  size_t EstimateCurrentMemoryConsumption() 
const;
 
  725  void TriggerCachingAfterTimeout();
 
  727  std::vector<WasmCode*> PublishCode(base::Vector<UnpublishedWasmCode> codes);
 
  730  void AddCompilationUnitInternal(CompilationUnitBuilder* builder,
 
  732                                  uint8_t function_progress);
 
  737  void TriggerOutstandingCallbacks();
 
  740  void TriggerCallbacks(base::EnumSet<CompilationEvent>);
 
  742  void PublishCompilationResults(
 
  743      std::vector<UnpublishedWasmCode> unpublished_code);
 
  796  std::vector<std::unique_ptr<CompilationEventCallback>> 
callbacks_;
 
  816  struct PublishState {
 
  825  using RequiredBaselineTierField = base::BitField8<ExecutionTier, 0, 2>;
 
  826  using RequiredTopTierField = base::BitField8<ExecutionTier, 2, 2>;
 
  827  using ReachedTierField = base::BitField8<ExecutionTier, 4, 2>;
 
  830CompilationStateImpl* Impl(CompilationState* compilation_state) {
 
  831  return reinterpret_cast<CompilationStateImpl*
>(compilation_state);
 
  833const CompilationStateImpl* Impl(
const CompilationState* compilation_state) {
 
  834  return reinterpret_cast<const CompilationStateImpl*
>(compilation_state);
 
  837CompilationStateImpl* BackgroundCompileScope::compilation_state()
 const {
 
  842size_t CompilationStateImpl::EstimateCurrentMemoryConsumption()
 const {
 
  844  size_t result = 
sizeof(CompilationStateImpl);
 
  847    base::MutexGuard guard{&
mutex_};
 
  859  constexpr size_t kAssumedNumberOfCallbacks = 4;
 
  860  constexpr size_t size_of_vector =
 
  861      kAssumedNumberOfCallbacks *
 
  862      sizeof(std::unique_ptr<CompilationEventCallback>);
 
  865  constexpr size_t size_of_payload =
 
  866      kAssumedNumberOfCallbacks * 
sizeof(CompilationEventCallback);
 
  867  result += size_of_vector + size_of_payload;
 
  869  if (
v8_flags.trace_wasm_offheap_memory) {
 
  875bool BackgroundCompileScope::cancelled()
 const {
 
  885CompilationState::~CompilationState() { Impl(
this)->~CompilationStateImpl(); }
 
  887void CompilationState::InitCompileJob() { Impl(
this)->InitCompileJob(); }
 
  889void CompilationState::CancelCompilation() {
 
  890  Impl(
this)->CancelCompilation(CompilationStateImpl::kCancelUnconditionally);
 
 
  893void CompilationState::CancelInitialCompilation() {
 
  894  Impl(
this)->CancelCompilation(
 
  895      CompilationStateImpl::kCancelInitialCompilation);
 
 
  898void CompilationState::SetError() { Impl(
this)->SetError(); }
 
  900void CompilationState::SetWireBytesStorage(
 
  901    std::shared_ptr<WireBytesStorage> wire_bytes_storage) {
 
  902  Impl(
this)->SetWireBytesStorage(std::move(wire_bytes_storage));
 
 
  905std::shared_ptr<WireBytesStorage> CompilationState::GetWireBytesStorage()
 
  907  return Impl(
this)->GetWireBytesStorage();
 
 
  910void CompilationState::AddCallback(
 
  911    std::unique_ptr<CompilationEventCallback> 
callback) {
 
  912  return Impl(
this)->AddCallback(std::move(
callback));
 
 
  915void CompilationState::TierUpAllFunctions() {
 
  916  Impl(
this)->TierUpAllFunctions();
 
 
  919void CompilationState::AllowAnotherTopTierJob(uint32_t func_index) {
 
  920  Impl(
this)->AllowAnotherTopTierJob(func_index);
 
 
  923void CompilationState::AllowAnotherTopTierJobForAllFunctions() {
 
  924  Impl(
this)->AllowAnotherTopTierJobForAllFunctions();
 
 
  927void CompilationState::InitializeAfterDeserialization(
 
  930  Impl(
this)->InitializeCompilationProgressAfterDeserialization(
 
  931      lazy_functions, eager_functions);
 
 
  934bool CompilationState::failed()
 const { 
return Impl(
this)->failed(); }
 
  936bool CompilationState::baseline_compilation_finished()
 const {
 
  937  return Impl(
this)->baseline_compilation_finished();
 
 
  940void CompilationState::set_compilation_id(
int compilation_id) {
 
  941  Impl(
this)->set_compilation_id(compilation_id);
 
 
  944size_t CompilationState::EstimateCurrentMemoryConsumption()
 const {
 
  945  return Impl(
this)->EstimateCurrentMemoryConsumption();
 
 
  948std::vector<WasmCode*> CompilationState::PublishCode(
 
  950  return Impl(
this)->PublishCode(unpublished_code);
 
 
  954std::unique_ptr<CompilationState> CompilationState::New(
 
  955    const std::shared_ptr<NativeModule>& native_module,
 
  956    std::shared_ptr<Counters> async_counters,
 
  958  return std::unique_ptr<CompilationState>(
reinterpret_cast<CompilationState*
>(
 
  959      new CompilationStateImpl(std::move(native_module),
 
  960                               std::move(async_counters), detected_features)));
 
 
  964  return Impl(
this)->detected_features();
 
 
  969  return Impl(
this)->UpdateDetectedFeatures(detected_features);
 
 
  980    case WasmCompilationHintTier::kDefault:
 
  982    case WasmCompilationHintTier::kBaseline:
 
  983      return ExecutionTier::kLiftoff;
 
  984    case WasmCompilationHintTier::kOptimized:
 
  985      return ExecutionTier::kTurbofan;
 
  990const WasmCompilationHint* GetCompilationHint(
const WasmModule* module,
 
  991                                              uint32_t func_index) {
 
  992  DCHECK_LE(module->num_imported_functions, func_index);
 
  993  uint32_t hint_index = declared_function_index(module, func_index);
 
  994  const std::vector<WasmCompilationHint>& compilation_hints =
 
  995      module->compilation_hints;
 
  996  if (hint_index < compilation_hints.size()) {
 
  997    return &compilation_hints[hint_index];
 
 1002CompileStrategy GetCompileStrategy(
const WasmModule* module,
 
 1003                                   WasmEnabledFeatures enabled_features,
 
 1004                                   uint32_t func_index, 
bool lazy_module) {
 
 1005  if (lazy_module) 
return CompileStrategy::kLazy;
 
 1006  if (!enabled_features.has_compilation_hints()) {
 
 1007    return CompileStrategy::kDefault;
 
 1009  auto* hint = GetCompilationHint(module, func_index);
 
 1010  if (hint == 
nullptr) 
return CompileStrategy::kDefault;
 
 1011  switch (hint->strategy) {
 
 1012    case WasmCompilationHintStrategy::kLazy:
 
 1013      return CompileStrategy::kLazy;
 
 1014    case WasmCompilationHintStrategy::kEager:
 
 1015      return CompileStrategy::kEager;
 
 1016    case WasmCompilationHintStrategy::kLazyBaselineEagerTopTier:
 
 1017      return CompileStrategy::kLazyBaselineEagerTopTier;
 
 1018    case WasmCompilationHintStrategy::kDefault:
 
 1019      return CompileStrategy::kDefault;
 
 1023struct ExecutionTierPair {
 
 1032ExecutionTierPair GetDefaultTiersPerModule(NativeModule* native_module,
 
 1033                                           DebugState is_in_debug_state,
 
 1035  const WasmModule* module = native_module->module();
 
 1037    return {ExecutionTier::kNone, ExecutionTier::kNone};
 
 1040    DCHECK(!is_in_debug_state);
 
 1041    return {ExecutionTier::kTurbofan, ExecutionTier::kTurbofan};
 
 1043  if (is_in_debug_state) {
 
 1044    return {ExecutionTier::kLiftoff, ExecutionTier::kLiftoff};
 
 1047      v8_flags.liftoff ? ExecutionTier::kLiftoff : ExecutionTier::kTurbofan;
 
 1048  bool eager_tier_up = !
v8_flags.wasm_dynamic_tiering && 
v8_flags.wasm_tier_up;
 
 1054ExecutionTierPair GetLazyCompilationTiers(NativeModule* native_module,
 
 1055                                          uint32_t func_index,
 
 1056                                          DebugState is_in_debug_state) {
 
 1059  constexpr bool kNotLazy = 
false;
 
 1060  ExecutionTierPair tiers =
 
 1061      GetDefaultTiersPerModule(native_module, is_in_debug_state, kNotLazy);
 
 1063  if (is_in_debug_state) 
return tiers;
 
 1066  if (native_module->enabled_features().has_compilation_hints()) {
 
 1067    if (
auto* hint = GetCompilationHint(native_module->module(), func_index)) {
 
 1068      tiers.baseline_tier =
 
 1069          ApplyHintToExecutionTier(hint->baseline_tier, tiers.baseline_tier);
 
 1070      tiers.top_tier = ApplyHintToExecutionTier(hint->top_tier, tiers.top_tier);
 
 1076                      static_cast<uint32_t
>(
v8_flags.wasm_tier_up_filter))) {
 
 1077    tiers.top_tier = tiers.baseline_tier;
 
 1081  static_assert(ExecutionTier::kLiftoff < ExecutionTier::kTurbofan,
 
 1082                "Assume an order on execution tiers");
 
 1083  if (tiers.baseline_tier > tiers.top_tier) {
 
 1084    tiers.top_tier = tiers.baseline_tier;
 
 1092class CompilationUnitBuilder {
 
 1094  explicit CompilationUnitBuilder(NativeModule* native_module)
 
 1097  void AddBaselineUnit(
int func_index, ExecutionTier tier) {
 
 1101  void AddTopTierUnit(
int func_index, ExecutionTier tier) {
 
 1107    compilation_state()->CommitCompilationUnits(base::VectorOf(
baseline_units_),
 
 1120  CompilationStateImpl* compilation_state()
 const {
 
 1131                                    base::Vector<const uint8_t> code,
 
 1132                                    WasmEnabledFeatures enabled_features,
 
 1133                                    WasmDetectedFeatures* detected_features) {
 
 1137  if (module->function_was_validated(func_index)) 
return {};
 
 1138  const WasmFunction* func = &
module->functions[func_index];
 
 1139  bool is_shared = 
module->type(func->sig_index).is_shared;
 
 1140  FunctionBody body{func->sig, func->code.offset(), code.begin(), code.end(),
 
 1143                                             detected_features, body);
 
 1144  if (
result.ok()) 
module->set_function_validated(func_index);
 
 1148enum OnlyLazyFunctions : 
bool {
 
 1149  kAllFunctions = 
false,
 
 1150  kOnlyLazyFunctions = 
true,
 
 1153bool IsLazyModule(
const WasmModule* module) {
 
 1154  return v8_flags.wasm_lazy_compilation ||
 
 1158class CompileLazyTimingScope {
 
 1160  CompileLazyTimingScope(Counters* counters, NativeModule* native_module)
 
 1165  ~CompileLazyTimingScope() {
 
 1166    base::TimeDelta elapsed = 
timer_.Elapsed();
 
 1167    native_module_->AddLazyCompilationTimeSample(elapsed.InMicroseconds());
 
 1168    counters_->wasm_lazy_compile_time()->AddTimedSample(elapsed);
 
 1183  NativeModule* native_module = trusted_instance_data->native_module();
 
 1184  Counters* counters = isolate->counters();
 
 1189  std::optional<CompileLazyTimingScope> lazy_compile_time_scope;
 
 1190  if (base::TimeTicks::IsHighResolution()) {
 
 1191    lazy_compile_time_scope.emplace(counters, native_module);
 
 1196  TRACE_LAZY(
"Compiling wasm-function#%d.\n", func_index);
 
 1198  CompilationStateImpl* compilation_state =
 
 1201  ExecutionTierPair tiers =
 
 1202      GetLazyCompilationTiers(native_module, func_index, is_in_debug_state);
 
 1207      func_index, tiers.baseline_tier,
 
 1212      &env, compilation_state->GetWireBytesStorage().get(), counters,
 
 1213      &detected_features);
 
 1214  compilation_state->OnCompilationStopped(detected_features);
 
 1235  counters->wasm_lazily_compiled_functions()->Increment();
 
 1238  const bool lazy_module = IsLazyModule(module);
 
 1239  if (GetCompileStrategy(module, native_module->
enabled_features(), func_index,
 
 1240                         lazy_module) == CompileStrategy::kLazy &&
 
 1241      tiers.baseline_tier < tiers.top_tier) {
 
 1244    compilation_state->CommitTopTierCompilationUnit(tiering_unit);
 
 
 1254  CompilationStateImpl* compilation_state =
 
 1256  const WasmFunction* func = &
module->functions[func_index];
 
 1258      compilation_state->GetWireBytesStorage()->GetCode(func->
code);
 
 1266      ValidateSingleFunction(&validation_zone, module, func_index, code,
 
 1267                             enabled_features, &unused_detected_features);
 
 1273                                             std::move(decode_result).error()));
 
 
 1296        instance_data_(trusted_instance_data),
 
 1297        module_(trusted_instance_data->module()),
 
 1299        feedback_for_function_(
module_->type_feedback.feedback_for_function) {
 
 1300    queue_.insert(func_index);
 
 
 1306    while (!queue_.empty()) {
 
 1307      auto next = queue_.cbegin();
 
 1308      ProcessFunction(*next);
 
 
 1313  void ProcessFunction(
int func_index);
 
 1317      for (
int j = 0; j < csf.num_cases(); j++) {
 
 1318        int func = csf.function_index(j);
 
 1320        if (csf.call_count(j) == 0) 
continue;
 
 1322        auto existing = feedback_for_function_.find(func);
 
 1323        if (existing != feedback_for_function_.end() &&
 
 1324            !existing->second.feedback_vector.empty()) {
 
 1325          if (!existing->second.needs_reprocessing_after_deopt) {
 
 1329          existing->second.needs_reprocessing_after_deopt = 
false;
 
 1331        queue_.insert(func);
 
 
 
 1348  return obj == 
ReadOnlyRoots{isolate}.wasm_cross_instance_call_symbol();
 
 
 1355                int func_index, 
int num_calls)
 
 1357        instance_data_(trusted_instance_data),
 
 1361            trusted_instance_data->module()->num_imported_functions)),
 
 
 1366        Cast<WasmFuncRef>(funcref)->internal(
isolate_);
 
 1368    if (internal_function->implicit_arg() != instance_data_) {
 
 1369      has_non_inlineable_targets_ = 
true;
 
 1374      has_non_inlineable_targets_ = 
true;
 
 1377    AddCall(internal_function->function_index(), 
count);
 
 
 1384      has_non_inlineable_targets_ = 
true;
 
 1387    Tagged<Smi> target_truncated_smi = Cast<Smi>(target_truncated_obj);
 
 1402        wasm::GetWasmCodeManager()->LookupCode(
nullptr, entry);
 
 1403    if (!code || code->native_module() != instance_data_->native_module() ||
 
 1404        code->IsAnonymous()) {
 
 1406      has_non_inlineable_targets_ = 
true;
 
 1409    DCHECK_EQ(code->kind(), WasmCode::Kind::kWasmFunction);
 
 1410    uint32_t func_idx = code->index();
 
 1411    AddCall(func_idx, 
count);
 
 
 1416    if (
static_cast<size_t>(cache_usage_) == targets_cache_.size() ||
 
 1418      is_megamorphic_ = 
true;
 
 1422    int insertion_index = 0;
 
 1423    while (insertion_index < cache_usage_ &&
 
 1424           counts_cache_[insertion_index] >= 
count) {
 
 1427    for (
int shifted_index = cache_usage_ - 1; shifted_index >= insertion_index;
 
 1429      targets_cache_[shifted_index + 1] = targets_cache_[shifted_index];
 
 1430      counts_cache_[shifted_index + 1] = counts_cache_[shifted_index];
 
 1432    targets_cache_[insertion_index] = 
target;
 
 1433    counts_cache_[insertion_index] = 
count;
 
 
 1438    auto end = targets_cache_.begin() + cache_usage_;
 
 1440    return std::find(targets_cache_.begin(), 
end, target) != 
end;
 
 
 1445    result_[seen_calls_] = feedback;
 
 
 1450    if (is_megamorphic_) {
 
 1451      if (
v8_flags.trace_wasm_inlining) {
 
 1455      AddResult(CallSiteFeedback::CreateMegamorphic());
 
 1456    } 
else if (cache_usage_ == 0) {
 
 1458    } 
else if (cache_usage_ == 1) {
 
 1459      if (
v8_flags.trace_wasm_inlining) {
 
 1460        PrintF(
"[function %d: call #%d inlineable (monomorphic)]\n",
 
 1465      if (
v8_flags.trace_wasm_inlining) {
 
 1466        PrintF(
"[function %d: call #%d inlineable (polymorphic %d)]\n",
 
 1472      for (
int i = 0; 
i < cache_usage_; 
i++) {
 
 1473        polymorphic[
i].function_index = targets_cache_[
i];
 
 1474        polymorphic[
i].absolute_call_frequency = counts_cache_[
i];
 
 1478    result_[seen_calls_ - 1].set_has_non_inlineable_targets(
 
 1479        has_non_inlineable_targets_);
 
 1482    has_non_inlineable_targets_ = 
false;
 
 1483    is_megamorphic_ = 
false;
 
 
 1500  int seen_calls_ = 0;
 
 1503  int cache_usage_{0};
 
 1506  bool has_non_inlineable_targets_ = 
false;
 
 1509  bool is_megamorphic_ = 
false;
 
 
 1512void TransitiveTypeFeedbackProcessor::ProcessFunction(
int func_index) {
 
 1515      instance_data_->feedback_vectors()->get(which_vector);
 
 1516  if (!IsFixedArray(maybe_feedback)) 
return;
 
 1519      module_->type_feedback.feedback_for_function[func_index]
 
 1520          .call_targets.as_vector();
 
 1546  int checked_feedback_length = feedback->length();
 
 1549                   checked_feedback_length / 2);
 
 1550  for (
int i = 0; 
i < checked_feedback_length; 
i += 2) {
 
 1551    uint32_t sentinel_or_target = call_targets[
i / 2];
 
 1555    if (sentinel_or_target != FunctionTypeFeedback::kCallRef &&
 
 1556        sentinel_or_target != FunctionTypeFeedback::kCallIndirect) {
 
 1558      int count = Smi::ToInt(first_slot);
 
 1563      fm.
AddCall(
static_cast<int>(sentinel_or_target), 
count);
 
 1564    } 
else if (
IsSmi(second_slot) && Smi::ToInt(second_slot) == 0) {
 
 1567      if (
v8_flags.trace_wasm_inlining) {
 
 1568        PrintF(
"[function %d: call #%d: uninitialized]\n", func_index, 
i / 2);
 
 1570    } 
else if (IsWasmFuncRef(first_slot)) {
 
 1572      DCHECK_EQ(sentinel_or_target, FunctionTypeFeedback::kCallRef);
 
 1573      int count = Smi::ToInt(second_slot);
 
 1577      DCHECK_EQ(sentinel_or_target, FunctionTypeFeedback::kCallIndirect);
 
 1578      int count = Smi::ToInt(second_slot);
 
 1580    } 
else if (IsFixedArray(first_slot)) {
 
 1583      DCHECK(IsUndefined(second_slot));
 
 1584      int checked_polymorphic_length = polymorphic->length();
 
 1586      if (sentinel_or_target == FunctionTypeFeedback::kCallRef) {
 
 1587        for (
int j = 0; j < checked_polymorphic_length; j += 2) {
 
 1589          int count = Smi::ToInt(polymorphic->get(j + 1));
 
 1593        DCHECK_EQ(sentinel_or_target, FunctionTypeFeedback::kCallIndirect);
 
 1594        for (
int j = 0; j < checked_polymorphic_length; j += 2) {
 
 1596          int count = Smi::ToInt(polymorphic->get(j + 1));
 
 1601      DCHECK(IsUndefined(second_slot));
 
 1608        first_slot != 
ReadOnlyRoots{isolate_}.megamorphic_symbol()) {
 
 1614          feedback_for_function_[func_index].feedback_vector;
 
 1615      size_t feedback_index = 
i / 2;
 
 1616      if (feedback_index < existing.
size()) {
 
 1624        for (
int j = 0; j < old_feedback.
num_cases(); ++j) {
 
 1634            DCHECK_GE(
static_cast<uint32_t
>(old_target_function_index),
 
 1635                      instance_data_->module()->num_imported_functions);
 
 1644  EnqueueCallees(
result.as_vector());
 
 1646            feedback_for_function_[func_index].call_targets.size());
 
 1647  feedback_for_function_[func_index].feedback_vector = std::move(
result);
 
 
 1653  NativeModule* native_module = trusted_instance_data->native_module();
 
 1654  CompilationStateImpl* compilation_state =
 
 1663    int array_index = wasm::declared_function_index(module, func_index);
 
 1664    trusted_instance_data->tiering_budget_array()[array_index].store(
 
 1665        v8_flags.wasm_tiering_budget, std::memory_order_relaxed);
 
 1666    int& stored_priority =
 
 1667        module->type_feedback.feedback_for_function[func_index].tierup_priority;
 
 1668    if (stored_priority < 
kMaxInt) ++stored_priority;
 
 1683    TransitiveTypeFeedbackProcessor::Process(isolate, trusted_instance_data,
 
 1687  compilation_state->AddTopTierPriorityCompilationUnit(tiering_unit, 
priority);
 
 
 1693  NativeModule* native_module = trusted_instance_data->native_module();
 
 1695    TransitiveTypeFeedbackProcessor::Process(isolate, trusted_instance_data,
 
 1698  wasm::GetWasmEngine()->CompileFunction(isolate->counters(), native_module,
 
 1700                                         wasm::ExecutionTier::kTurbofan);
 
 
 1706  NativeModule* native_module = trusted_instance_data->native_module();
 
 1712  for (uint32_t func_index = 
start; func_index < 
end; func_index++) {
 
 1713    if (!native_module->
HasCodeWithTier(func_index, ExecutionTier::kTurbofan)) {
 
 
 1721      ->InitializeCompilationProgress(
nullptr);
 
 
 1725                             Isolate* isolate, 
bool is_initial_compilation) {
 
 1727  static constexpr std::pair<WasmDetectedFeature, Feature> kUseCounters[] = {
 
 1728      {WasmDetectedFeature::shared_memory, Feature::kWasmSharedMemory},
 
 1729      {WasmDetectedFeature::reftypes, Feature::kWasmRefTypes},
 
 1730      {WasmDetectedFeature::simd, Feature::kWasmSimdOpcodes},
 
 1731      {WasmDetectedFeature::threads, Feature::kWasmThreadOpcodes},
 
 1732      {WasmDetectedFeature::legacy_eh, Feature::kWasmExceptionHandling},
 
 1733      {WasmDetectedFeature::memory64, Feature::kWasmMemory64},
 
 1734      {WasmDetectedFeature::multi_memory, Feature::kWasmMultiMemory},
 
 1735      {WasmDetectedFeature::gc, Feature::kWasmGC},
 
 1736      {WasmDetectedFeature::imported_strings, Feature::kWasmImportedStrings},
 
 1737      {WasmDetectedFeature::imported_strings_utf8,
 
 1738       Feature::kWasmImportedStringsUtf8},
 
 1739      {WasmDetectedFeature::return_call, Feature::kWasmReturnCall},
 
 1740      {WasmDetectedFeature::extended_const, Feature::kWasmExtendedConst},
 
 1741      {WasmDetectedFeature::relaxed_simd, Feature::kWasmRelaxedSimd},
 
 1742      {WasmDetectedFeature::type_reflection, Feature::kWasmTypeReflection},
 
 1743      {WasmDetectedFeature::exnref, Feature::kWasmExnRef},
 
 1744      {WasmDetectedFeature::typed_funcref, Feature::kWasmTypedFuncRef},
 
 1745      {WasmDetectedFeature::jspi, Feature::kWasmJavaScriptPromiseIntegration},
 
 1746      {WasmDetectedFeature::branch_hinting, Feature::kWasmBranchHinting},
 
 1754        WasmDetectedFeature::stringref,  
 
 1756    for (
auto no_use_counter_feature : kIntentionallyNoUseCounter) {
 
 1757      if (feat == no_use_counter_feature) 
return true;
 
 1759    for (
auto [feature, use_counter] : kUseCounters) {
 
 1760      if (feat == feature) 
return true;
 
 1764#define CHECK_USE_COUNTER(feat, ...) \ 
 1765  static_assert(check_use_counter(WasmDetectedFeature::feat)); 
 1769#undef CHECK_USE_COUNTER 
 1771  static constexpr size_t kMaxFeatures = 
arraysize(kUseCounters) + 1;
 
 1773  if (is_initial_compilation) {
 
 1777    use_counter_features.
push_back(Feature::kWasmModuleCompilation);
 
 1780  for (
auto [wasm_feature, feature] : kUseCounters) {
 
 1781    if (!detected_features.
contains(wasm_feature)) 
continue;
 
 1782    use_counter_features.
push_back(feature);
 
 1784  if (use_counter_features.
empty()) 
return;
 
 1786  isolate->CountUsage(base::VectorOf(use_counter_features));
 
 1790  if (
v8_flags.correctness_fuzzer_suppressions) {
 
 1791    if (detected_features.has_relaxed_simd()) {
 
 1792      PrintF(
"Warning: This run cannot be compared across architectures.\n");
 
 
 1800  if (!type.is_object_reference() || !type.has_index()) 
return false;
 
 1801  ModuleTypeIndex reftype = type.ref_index();
 
 1802  if (!module->
has_array(reftype)) 
return false;
 
 1803  return module->canonical_type_id(reftype) ==
 
 1804         TypeCanonicalizer::kPredefinedArrayI16Index;
 
 1807bool IsI8Array(wasm::ValueType type, 
const WasmModule* module,
 
 1808               bool allow_nullable) {
 
 1809  if (!type.is_object_reference() || !type.has_index()) 
return false;
 
 1810  if (!allow_nullable && type.is_nullable()) 
return false;
 
 1811  ModuleTypeIndex reftype = type.ref_index();
 
 1812  if (!module->has_array(reftype)) 
return false;
 
 1813  return module->canonical_type_id(reftype) ==
 
 1814         TypeCanonicalizer::kPredefinedArrayI8Index;
 
 1822uint32_t ImportStartOffset(base::Vector<const uint8_t> wire_bytes,
 
 1823                           uint32_t module_name_start) {
 
 1825  uint32_t 
offset = module_name_start - 1;  
 
 1827  while (
offset > 0 && (wire_bytes[
offset - 1] & 0x80) != 0) {
 
 1842  if (imports.
empty()) 
return {};
 
 1849  static constexpr ValueType kReps_e_i[] = {kRefExtern, 
kI32};
 
 1850  static constexpr ValueType kReps_e_rr[] = {kRefExtern, kExternRef,
 
 1852  static constexpr ValueType kReps_e_rii[] = {kRefExtern, kExternRef, 
kI32,
 
 1855  static constexpr ValueType kReps_i_rr[] = {
kI32, kExternRef, kExternRef};
 
 1857  static constexpr FunctionSig kSig_e_i(1, 1, kReps_e_i);
 
 1858  static constexpr FunctionSig kSig_e_r(1, 1, kReps_e_rr);
 
 1859  static constexpr FunctionSig kSig_e_rr(1, 2, kReps_e_rr);
 
 1860  static constexpr FunctionSig kSig_e_rii(1, 3, kReps_e_rii);
 
 1862  static constexpr FunctionSig kSig_i_r(1, 1, kReps_i_ri);
 
 1863  static constexpr FunctionSig kSig_i_ri(1, 2, kReps_i_ri);
 
 1864  static constexpr FunctionSig kSig_i_rr(1, 2, kReps_i_rr);
 
 1866  std::vector<WellKnownImport> statuses;
 
 1869    const WasmImport& 
import = module->import_table[i];
 
 1874            import.module_name.offset(), 
import.module_name.end_offset()))) {
 
 1876          !module->
globals[
import.index].type.is_reference_to(
 
 1877              HeapType::kExtern) ||
 
 1878          module->
globals[
import.index].mutability != 
false) {
 
 1880            wire_bytes.
data() + 
import.field_name.offset(),
 
 1881            import.field_name.length());
 
 1883            ImportStartOffset(wire_bytes, 
import.module_name.offset()),
 
 1884            "String constant import #%zu \"%.*s\" must be an immutable global " 
 1885            "subtyping externref",
 
 1886            i, name.
length(), name.start());
 
 1893        import.module_name.offset(), 
import.module_name.end_offset());
 
 1894    constexpr size_t kMinInterestingLength = 10;
 
 1895    if (module_name.
size() < kMinInterestingLength ||
 
 1896        module_name.
SubVector(0, 5) != base::StaticOneByteVector(
"wasm:")) {
 
 1897      statuses.push_back(WellKnownImport::kUninstantiated);
 
 1902    const WasmFunction& func = 
module->functions[import.index];
 
 1907    if (collection == base::StaticOneByteVector(
"js-string") &&
 
 1908        imports.
contains(CompileTimeImport::kJsString)) {
 
 1909#define RETURN_ERROR(module_name_string, import_name)                     \ 
 1910  uint32_t error_offset =                                                 \ 
 1911      ImportStartOffset(wire_bytes, import.module_name.offset());         \ 
 1912  return WasmError(error_offset,                                          \ 
 1913                   "Imported builtin function \"wasm:" module_name_string \ 
 1914                   "\" \"" import_name "\" has incorrect signature") 
 1916#define CHECK_SIG(import_name, kSigName, kEnumName)      \ 
 1917  if (name == base::StaticOneByteVector(#import_name)) { \ 
 1918    if (*sig != kSigName) {                              \ 
 1919      RETURN_ERROR("js-string", #import_name);           \ 
 1921    status = WellKnownImport::kEnumName;                 \ 
 1922    detected->add_imported_strings();                    \ 
 1936      if (name == base::StaticOneByteVector(
"fromCharCodeArray")) {
 
 1937        if (
sig->parameter_count() != 3 || 
sig->return_count() != 1 ||
 
 1938            !IsI16Array(
sig->GetParam(0), module) ||  
 
 1941            sig->GetReturn() != kRefExtern) {
 
 1944        detected->add_imported_strings();
 
 1945        status = WellKnownImport::kStringFromWtf16Array;
 
 1946      } 
else if (name == base::StaticOneByteVector(
"intoCharCodeArray")) {
 
 1947        if (
sig->parameter_count() != 3 || 
sig->return_count() != 1 ||
 
 1948            sig->GetParam(0) != kExternRef ||
 
 1949            !IsI16Array(
sig->GetParam(1), module) ||  
 
 1954        status = WellKnownImport::kStringToWtf16Array;
 
 1955        detected->add_imported_strings();
 
 1958    } 
else if (collection == base::StaticOneByteVector(
"text-encoder") &&
 
 1959               imports.
contains(CompileTimeImport::kTextEncoder)) {
 
 1960      if (name == base::StaticOneByteVector(
"measureStringAsUTF8")) {
 
 1961        if (*
sig != kSig_i_r) {
 
 1964        status = WellKnownImport::kStringMeasureUtf8;
 
 1965        detected->add_imported_strings_utf8();
 
 1967                 base::StaticOneByteVector(
"encodeStringIntoUTF8Array")) {
 
 1968        if (
sig->parameter_count() != 3 || 
sig->return_count() != 1 ||
 
 1969            sig->GetParam(0) != kExternRef ||              
 
 1970            !IsI8Array(
sig->GetParam(1), module, 
true) ||  
 
 1973          RETURN_ERROR(
"text-encoder", 
"encodeStringIntoUTF8Array");
 
 1975        status = WellKnownImport::kStringIntoUtf8Array;
 
 1976        detected->add_imported_strings_utf8();
 
 1977      } 
else if (name == base::StaticOneByteVector(
"encodeStringToUTF8Array")) {
 
 1978        if (
sig->parameter_count() != 1 || 
sig->return_count() != 1 ||
 
 1979            sig->GetParam(0) != kExternRef ||
 
 1980            !IsI8Array(
sig->GetReturn(), module, 
false)) {
 
 1981          RETURN_ERROR(
"text-encoder", 
"encodeStringToUTF8Array");
 
 1983        status = WellKnownImport::kStringToUtf8Array;
 
 1984        detected->add_imported_strings_utf8();
 
 1986    } 
else if (collection == base::StaticOneByteVector(
"text-decoder") &&
 
 1987               imports.
contains(CompileTimeImport::kTextDecoder)) {
 
 1988      if (name == base::StaticOneByteVector(
"decodeStringFromUTF8Array")) {
 
 1989        if (
sig->parameter_count() != 3 || 
sig->return_count() != 1 ||
 
 1990            !IsI8Array(
sig->GetParam(0), module, 
true) ||  
 
 1993            sig->GetReturn() != kRefExtern) {
 
 1994          RETURN_ERROR(
"text-decoder", 
"decodeStringFromUTF8Array");
 
 1996        status = WellKnownImport::kStringFromUtf8Array;
 
 1997        detected->add_imported_strings_utf8();
 
 2001    statuses.push_back(status);
 
 2009    module->type_feedback.well_known_imports.Initialize(
 
 2010        base::VectorOf(statuses));
 
 
 2017enum CompilationExecutionResult : int8_t { kNoMoreUnits, kYield };
 
 2019const char* GetCompilationEventName(
const WasmCompilationUnit& 
unit,
 
 2020                                    const CompilationEnv& env) {
 
 2021  ExecutionTier tier = 
unit.tier();
 
 2022  if (tier == ExecutionTier::kLiftoff) {
 
 2023    return "wasm.BaselineCompilation";
 
 2025  if (tier == ExecutionTier::kTurbofan) {
 
 2026    return "wasm.TopTierCompilation";
 
 2028  if (
unit.func_index() <
 
 2029      static_cast<int>(env.module->num_imported_functions)) {
 
 2030    return "wasm.WasmToJSWrapperCompilation";
 
 2032  return "wasm.OtherCompilation";
 
 2035constexpr uint8_t kMainTaskId = 0;
 
 2038CompilationExecutionResult ExecuteCompilationUnits(
 
 2039    std::weak_ptr<NativeModule> native_module, Counters* counters,
 
 2040    JobDelegate* delegate, CompilationTier tier) {
 
 2041  TRACE_EVENT0(
"v8.wasm", 
"wasm.ExecuteCompilationUnits");
 
 2048  std::optional<CompilationEnv> env;
 
 2049  std::optional<base::FlushDenormalsScope> disable_denormals;
 
 2050  std::shared_ptr<WireBytesStorage> wire_bytes;
 
 2051  std::shared_ptr<const WasmModule> module;
 
 2054  static_assert(kMainTaskId == 0);
 
 2055  int task_id = delegate ? (
int{delegate->GetTaskId()} + 1) : kMainTaskId;
 
 2057  CompilationUnitQueues::Queue* queue;
 
 2058  std::optional<WasmCompilationUnit> 
unit;
 
 2060  WasmDetectedFeatures global_detected_features;
 
 2065    BackgroundCompileScope compile_scope(native_module);
 
 2066    if (compile_scope.cancelled()) 
return kYield;
 
 2067    env.emplace(CompilationEnv::ForModule(compile_scope.native_module()));
 
 2070    disable_denormals.emplace(
 
 2071        compile_scope.native_module()->compile_imports().contains(
 
 2072            CompileTimeImport::kDisableDenormalFloats));
 
 2073    wire_bytes = compile_scope.compilation_state()->GetWireBytesStorage();
 
 2074    module = compile_scope.native_module()->shared_module();
 
 2075    queue = compile_scope.compilation_state()->GetQueueForCompileTask(task_id);
 
 2077        compile_scope.compilation_state()->GetNextCompilationUnit(queue, tier);
 
 2078    if (!
unit) 
return kNoMoreUnits;
 
 2080  TRACE_COMPILE(
"ExecuteCompilationUnits (task id %d)\n", task_id);
 
 2082  std::vector<WasmCompilationResult> results_to_publish;
 
 2085    const char* event_name = GetCompilationEventName(
unit.value(), env.value());
 
 2087    while (
unit->tier() == current_tier) {
 
 2090      WasmDetectedFeatures per_function_detected_features;
 
 2092      WasmCompilationResult 
result =
 
 2093          unit->ExecuteCompilation(&env.value(), wire_bytes.get(), counters,
 
 2094                                   &per_function_detected_features);
 
 2095      global_detected_features.Add(per_function_detected_features);
 
 2096      bool compilation_succeeded = 
result.succeeded();
 
 2099      DCHECK_GE(
unit->func_index(), env->module->num_imported_functions);
 
 2100      results_to_publish.emplace_back(std::move(
result));
 
 2102      bool yield = delegate && delegate->ShouldYield();
 
 2105      BackgroundCompileScope compile_scope(native_module);
 
 2106      if (compile_scope.cancelled()) 
return kYield;
 
 2108      if (!compilation_succeeded) {
 
 2109        compile_scope.compilation_state()->SetError();
 
 2110        return kNoMoreUnits;
 
 2113      if (!
unit->for_debugging() && result_tier != current_tier) {
 
 2114        compile_scope.native_module()->AddLiftoffBailout();
 
 2119          !(
unit = compile_scope.compilation_state()->GetNextCompilationUnit(
 
 2121        std::vector<UnpublishedWasmCode> unpublished_code =
 
 2122            compile_scope.native_module()->AddCompiledCode(
 
 2123                base::VectorOf(results_to_publish));
 
 2124        results_to_publish.clear();
 
 2125        compile_scope.compilation_state()->SchedulePublishCompilationResults(
 
 2126            std::move(unpublished_code), tier);
 
 2127        compile_scope.compilation_state()->OnCompilationStopped(
 
 2128            global_detected_features);
 
 2129        return yield ? kYield : kNoMoreUnits;
 
 2135          queue->ShouldPublish(
static_cast<int>(results_to_publish.size()));
 
 2139      bool liftoff_finished = 
unit->tier() != current_tier &&
 
 2140                              unit->tier() == ExecutionTier::kTurbofan;
 
 2141      if (batch_full || liftoff_finished) {
 
 2142        std::vector<UnpublishedWasmCode> unpublished_code =
 
 2143            compile_scope.native_module()->AddCompiledCode(
 
 2144                base::VectorOf(results_to_publish));
 
 2145        results_to_publish.clear();
 
 2146        compile_scope.compilation_state()->SchedulePublishCompilationResults(
 
 2147            std::move(unpublished_code), tier);
 
 2154std::unique_ptr<CompilationUnitBuilder> InitializeCompilation(
 
 2155    Isolate* isolate, NativeModule* native_module,
 
 2156    ProfileInformation* pgo_info) {
 
 2157  CompilationStateImpl* compilation_state =
 
 2158      Impl(native_module->compilation_state());
 
 2159  auto builder = std::make_unique<CompilationUnitBuilder>(native_module);
 
 2160  compilation_state->InitializeCompilationProgress(pgo_info);
 
 2164bool MayCompriseLazyFunctions(
const WasmModule* module,
 
 2165                              WasmEnabledFeatures enabled_features) {
 
 2166  if (IsLazyModule(module)) 
return true;
 
 2167  if (enabled_features.has_compilation_hints()) 
return true;
 
 2168#ifdef ENABLE_SLOW_DCHECKS 
 2169  int start = 
module->num_imported_functions;
 
 2170  int end = 
start + module->num_declared_functions;
 
 2171  for (
int func_index = 
start; func_index < 
end; func_index++) {
 
 2172    SLOW_DCHECK(GetCompileStrategy(module, enabled_features, func_index,
 
 2173                                   false) != CompileStrategy::kLazy);
 
 2179class CompilationTimeCallback : 
public CompilationEventCallback {
 
 2182  explicit CompilationTimeCallback(
 
 2183      std::shared_ptr<Counters> async_counters,
 
 2184      std::shared_ptr<metrics::Recorder> metrics_recorder,
 
 2186      std::weak_ptr<NativeModule> native_module, CompileMode compile_mode)
 
 2194  void call(CompilationEvent compilation_event)
 override {
 
 2195    DCHECK(base::TimeTicks::IsHighResolution());
 
 2196    std::shared_ptr<NativeModule> native_module = 
native_module_.lock();
 
 2197    if (!native_module) 
return;
 
 2198    auto now = base::TimeTicks::Now();
 
 2200    if (compilation_event == CompilationEvent::kFinishedBaselineCompilation) {
 
 2204        TimedHistogram* histogram =
 
 2208        histogram->AddSample(
static_cast<int>(duration.InMicroseconds()));
 
 2218          native_module->liftoff_code_size(),      
 
 2219          native_module->liftoff_bailout_count(),  
 
 2220          duration.InMicroseconds()};              
 
 2223    if (compilation_event == CompilationEvent::kFailedCompilation) {
 
 2231          native_module->liftoff_code_size(),      
 
 2232          native_module->liftoff_bailout_count(),  
 
 2233          duration.InMicroseconds()};              
 
 2248                            base::Vector<const uint8_t> wire_bytes,
 
 2249                            WasmEnabledFeatures enabled_features,
 
 2250                            OnlyLazyFunctions only_lazy_functions,
 
 2251                            WasmDetectedFeatures* detected_features) {
 
 2253  if (only_lazy_functions &&
 
 2254      !MayCompriseLazyFunctions(module, enabled_features)) {
 
 2258  std::function<
bool(
int)> filter;  
 
 2259  if (only_lazy_functions) {
 
 2260    const bool is_lazy_module = IsLazyModule(module);
 
 2261    filter = [module, enabled_features, is_lazy_module](
int func_index) {
 
 2262      CompileStrategy strategy = GetCompileStrategy(module, enabled_features,
 
 2263                                                    func_index, is_lazy_module);
 
 2264      return strategy == CompileStrategy::kLazy ||
 
 2265             strategy == CompileStrategy::kLazyBaselineEagerTopTier;
 
 2274                            OnlyLazyFunctions only_lazy_functions) {
 
 2275  WasmDetectedFeatures detected_features;
 
 2278                        native_module.enabled_features(), only_lazy_functions,
 
 2279                        &detected_features);
 
 2280  if (!
result.has_error()) {
 
 2284    USE(native_module.compilation_state()->UpdateDetectedFeatures(
 
 2285        detected_features));
 
 2290void CompileNativeModule(Isolate* isolate,
 
 2292                         ErrorThrower* thrower,
 
 2293                         std::shared_ptr<NativeModule> native_module,
 
 2294                         ProfileInformation* pgo_info) {
 
 2296  const WasmModule* module = native_module->module();
 
 2299  auto* compilation_state = Impl(native_module->compilation_state());
 
 2300  if (base::TimeTicks::IsHighResolution()) {
 
 2301    compilation_state->AddCallback(std::make_unique<CompilationTimeCallback>(
 
 2302        isolate->async_counters(), isolate->metrics_recorder(), context_id,
 
 2303        native_module, CompilationTimeCallback::kSynchronous));
 
 2307  std::unique_ptr<CompilationUnitBuilder> builder =
 
 2308      InitializeCompilation(isolate, native_module.get(), pgo_info);
 
 2309  compilation_state->InitializeCompilationUnits(std::move(builder));
 
 2314  if (!
v8_flags.wasm_lazy_validation && module->origin == kWasmOrigin) {
 
 2315    DCHECK(!thrower->error());
 
 2316    if (WasmError validation_error =
 
 2318      thrower->CompileFailed(std::move(validation_error));
 
 2323  if (!compilation_state->failed()) {
 
 2324    compilation_state->WaitForCompilationEvent(
 
 2325        CompilationEvent::kFinishedBaselineCompilation);
 
 2328  if (compilation_state->failed()) {
 
 2330    WasmError validation_error =
 
 2332    CHECK(validation_error.has_error());
 
 2333    thrower->CompileFailed(std::move(validation_error));
 
 2337class BackgroundCompileJob final : 
public JobTask {
 
 2339  explicit BackgroundCompileJob(std::weak_ptr<NativeModule> native_module,
 
 2340                                std::shared_ptr<Counters> async_counters,
 
 2341                                CompilationTier tier)
 
 2347  void Run(JobDelegate* delegate)
 override {
 
 2349    if (!engine_scope) 
return;
 
 2354  size_t GetMaxConcurrency(
size_t worker_count)
 const override {
 
 2356    if (compile_scope.cancelled()) 
return 0;
 
 2357    size_t flag_limit = 
static_cast<size_t>(
 
 2358        std::max(1, 
v8_flags.wasm_num_compilation_tasks.value()));
 
 2361    return std::min(flag_limit,
 
 2362                    worker_count + compile_scope.compilation_state()
 
 2363                                       ->NumOutstandingCompilations(
tier_));
 
 2373std::shared_ptr<NativeModule> GetOrCompileNewNativeModule(
 
 2374    Isolate* isolate, WasmEnabledFeatures enabled_features,
 
 2375    WasmDetectedFeatures detected_features, CompileTimeImports compile_imports,
 
 2376    ErrorThrower* thrower, std::shared_ptr<const WasmModule> module,
 
 2377    base::OwnedVector<const uint8_t> wire_bytes, 
int compilation_id,
 
 2379  std::shared_ptr<NativeModule> native_module =
 
 2381          module->origin, wire_bytes.as_vector(), compile_imports, isolate);
 
 2382  if (native_module) 
return native_module;
 
 2385  std::optional<TimedHistogramScope> wasm_compile_module_time_scope;
 
 2386  if (base::TimeTicks::IsHighResolution()) {
 
 2388        isolate->counters(), module->origin, wasm_compile, module_time));
 
 2391  size_t code_size_estimate =
 
 2392      wasm::WasmCodeManager::EstimateNativeModuleCodeSize(module.get());
 
 2394      isolate, enabled_features, detected_features, std::move(compile_imports),
 
 2395      module, code_size_estimate);
 
 2396  native_module->SetWireBytes(std::move(wire_bytes));
 
 2397  native_module->compilation_state()->set_compilation_id(compilation_id);
 
 2401    CompileNativeModule(isolate, context_id, thrower, native_module, pgo_info);
 
 2404  if (thrower->error()) {
 
 2421    ErrorThrower* thrower, std::shared_ptr<const WasmModule> module,
 
 2424  std::shared_ptr<NativeModule> native_module = GetOrCompileNewNativeModule(
 
 2425      isolate, enabled_features, detected_features, std::move(compile_imports),
 
 2426      thrower, module, std::move(wire_bytes), compilation_id, context_id,
 
 2428  if (!native_module) 
return {};
 
 2435      native_module->compilation_state()->detected_features(), isolate, 
true);
 
 2437  return native_module;
 
 
 2440AsyncCompileJob::AsyncCompileJob(
 
 2445    std::shared_ptr<CompilationResultResolver> resolver, 
int compilation_id)
 
 2447      api_method_name_(api_method_name),
 
 2449      compile_imports_(
std::move(compile_imports)),
 
 2451      bytes_copy_(
std::move(bytes)),
 
 2456               "wasm.AsyncCompileJob");
 
 2463      isolate->global_handles()->Create(context->native_context());
 
 
 2513    *ptr++ = {declared_func_index, code};
 
 2517    size_t total_units_added = ptr - 
units.begin();
 
 2526    if ((total_units_added >= 16 &&
 
 2528        (total_units_added % (16 * 1024)) == 0 || ptr == 
units.end()) {
 
 
 2547    while (next < 
end) {
 
 2549              next, next + 1, std::memory_order_relaxed)) {
 
 
 2561        old_features, old_features | new_detected_features,
 
 2562        std::memory_order_relaxed)) {
 
 
 
 2582    TRACE_EVENT0(
"v8.wasm", 
"wasm.ValidateFunctionsStreaming");
 
 2587      validation_zone.Reset();
 
 
 
 2621                      uint32_t 
offset) 
override;
 
 2624                                uint32_t functions_mismatch_error_offset,
 
 2625                                std::shared_ptr<WireBytesStorage>,
 
 2626                                int code_section_start,
 
 2627                                int code_section_length) 
override;
 
 2630                           uint32_t 
offset) 
override;
 
 2635                        bool after_error) 
override;
 
 
 2663      std::make_unique<AsyncStreamingProcessor>(
this));
 
 
 2673        ->CancelCompilation(CompilationStateImpl::kCancelInitialCompilation);
 
 
 2687    std::shared_ptr<const WasmModule> module, 
size_t code_size_estimate) {
 
 2689  const bool has_shared_memory =
 
 2690      std::any_of(module->memories.begin(), module->memories.end(),
 
 2691                  [](
auto& memory) { return memory.is_shared; });
 
 2692  if (has_shared_memory) {
 
 
 2707    std::shared_ptr<const WasmModule> module, 
size_t code_size_estimate) {
 
 
 2735               "wasm.FinishAsyncCompile");
 
 2740  auto compilation_state = Impl(
native_module_->compilation_state());
 
 2750    std::unique_ptr<ProfileInformation> pgo_info =
 
 2753      compilation_state->ApplyPgoInfoLate(pgo_info.get());
 
 2758  if (!is_after_deserialization) {
 
 2765    int duration_usecs = 
static_cast<int>(duration.
InMicroseconds());
 
 2769    if (is_after_cache_hit || is_after_deserialization) {
 
 2774          is_after_deserialization,                 
 
 2776          !compilation_state->failed(),             
 
 2787  auto sourcemap_symbol =
 
 2788      module->debug_symbols[WasmDebugSymbols::Type::SourceMap];
 
 2789  if (script->type() == Script::Type::kWasm &&
 
 2791      !sourcemap_symbol.external_url.is_empty()) {
 
 2801                 "wasm.Debug.OnAfterCompile");
 
 
 2830  std::unique_ptr<AsyncCompileJob> job =
 
 2834  constexpr bool kValidate = 
true;
 
 2845    CHECK(!job->compile_imports_.empty());
 
 2848        &unused_detected_features);
 
 2849    CHECK(error.has_error());
 
 2850    thrower.CompileError(
"%s", error.message().c_str());
 
 
 2864        DCHECK(!last_event_.has_value());
 
 2869          std::shared_ptr<NativeModule> cached_native_module =
 
 2874            cached_native_module = 
nullptr;
 
 2884        DCHECK(!last_event_.has_value());
 
 2895    last_event_ = event;
 
 
 2904  std::optional<CompilationEvent> last_event_;
 
 
 2915    if (on_foreground) {
 
 
 
 2972  auto new_task = std::make_unique<CompileTask>(
this, 
true);
 
 
 2980  auto new_task = std::make_unique<CompileTask>(
this, 
true);
 
 
 2992  auto task = std::make_unique<CompileTask>(
this, 
false);
 
 2996  if (
v8_flags.wasm_num_compilation_tasks > 0) {
 
 
 3004template <
typename Step,
 
 3013template <
typename Step, 
typename... Args>
 
 3019template <
typename Step, 
typename... Args>
 
 3025template <
typename Step, 
typename... Args>
 
 3027  step_.reset(
new Step(std::forward<Args>(
args)...));
 
 
 3036                        std::shared_ptr<metrics::Recorder> metrics_recorder)
 
 
 3047                   "wasm.DecodeModule");
 
 3077      std::shared_ptr<WasmModule> module = std::move(
result).value();
 
 3078      size_t code_size_estimate =
 
 3081          std::move(module), 
true ,
 
 3082          true , code_size_estimate);
 
 
 
 3097                         bool start_compilation,
 
 3098                         bool lazy_functions_are_validated,
 
 3099                         size_t code_size_estimate)
 
 
 3127      if (!
v8_flags.wasm_lazy_validation &&
 
 3139    CompilationStateImpl* compilation_state =
 
 3141    compilation_state->AddCallback(
 
 3142        std::make_unique<CompilationStateCallback>(job));
 
 3144      auto compile_mode = job->
stream_ == 
nullptr 
 3145                              ? CompilationTimeCallback::kAsync
 
 3146                              : CompilationTimeCallback::kStreaming;
 
 3147      compilation_state->AddCallback(std::make_unique<CompilationTimeCallback>(
 
 3155      std::unique_ptr<CompilationUnitBuilder> builder = InitializeCompilation(
 
 3157      compilation_state->InitializeCompilationUnits(std::move(builder));
 
 3162        compilation_state->WaitForCompilationEvent(
 
 
 
 3211                 "wasm.OnCompilationSucceeded");
 
 
 3225      compilation_unit_builder_(nullptr) {}
 
 
 3262    offset += bytes_consumed;
 
 3263    bytes = bytes.SubVector(bytes_consumed, bytes.size());
 
 
 3271    int num_functions, uint32_t functions_mismatch_error_offset,
 
 3272    std::shared_ptr<WireBytesStorage> wire_bytes_storage,
 
 3273    int code_section_start, 
int code_section_length) {
 
 3280                                    functions_mismatch_error_offset)) {
 
 3285                             static_cast<uint32_t
>(code_section_length)});
 
 3297  size_t code_size_estimate =
 
 3299                                                          code_section_length);
 
 3305      false, code_size_estimate);
 
 3308  compilation_state->SetWireBytesStorage(std::move(wire_bytes_storage));
 
 
 3325  uint32_t func_index =
 
 3341  const bool lazy_module = 
v8_flags.wasm_lazy_compilation;
 
 3342  CompileStrategy strategy =
 
 3343      GetCompileStrategy(module, enabled_features, func_index, lazy_module);
 
 3345  bool validate_lazily_compiled_function =
 
 3348       (strategy == CompileStrategy::kLazy ||
 
 3349        strategy == CompileStrategy::kLazyBaselineEagerTopTier));
 
 3350  if (validate_lazily_compiled_function) {
 
 3358          std::make_unique<ValidateFunctionsStreamingJob>(
 
 
 3386  if (module_result.
failed()) after_error = 
true;
 
 3398            std::memory_order_relaxed);
 
 3436  std::shared_ptr<WasmModule> module = std::move(module_result).value();
 
 3448                          &detected_module_features)
 
 3459    size_t code_size_estimate =
 
 3462        std::move(module), 
true ,
 
 3463        false , code_size_estimate);
 
 3476  auto* module_size_histogram =
 
 3479  auto* num_functions_histogram =
 
 3481  num_functions_histogram->AddSample(
static_cast<int>(
num_functions_));
 
 3484  bool cache_hit = 
false;
 
 3485  if (!has_code_section) {
 
 3489    constexpr size_t kCodeSizeEstimate = 0;
 
 
 3534  std::optional<TimedHistogramScope> time_scope;
 
 3548  if (
result.is_null()) 
return false;
 
 
 3559CompilationStateImpl::CompilationStateImpl(
 
 3560    const std::shared_ptr<NativeModule>& native_module,
 
 3561    std::shared_ptr<Counters> async_counters,
 
 3567                               native_module->num_declared_functions()),
 
 3570void CompilationStateImpl::InitCompileJob() {
 
 3576      TaskPriority::kUserVisible,
 
 3577      std::make_unique<BackgroundCompileJob>(
 
 3580      TaskPriority::kUserVisible,
 
 3581      std::make_unique<BackgroundCompileJob>(
 
 3585void CompilationStateImpl::CancelCompilation(
 
 3586    CompilationStateImpl::CancellationPolicy cancellation_policy) {
 
 3589  if (cancellation_policy == kCancelInitialCompilation &&
 
 3591          CompilationEvent::kFinishedBaselineCompilation)) {
 
 3604bool CompilationStateImpl::cancelled()
 const {
 
 3608void CompilationStateImpl::ApplyCompilationHintToInitialProgress(
 
 3609    const WasmCompilationHint& hint, 
size_t hint_idx) {
 
 3612  ExecutionTier old_baseline_tier = RequiredBaselineTierField::decode(progress);
 
 3613  ExecutionTier old_top_tier = RequiredTopTierField::decode(progress);
 
 3617      ApplyHintToExecutionTier(hint.baseline_tier, old_baseline_tier);
 
 3619      ApplyHintToExecutionTier(hint.top_tier, old_top_tier);
 
 3620  switch (hint.strategy) {
 
 3621    case WasmCompilationHintStrategy::kDefault:
 
 3623      if (old_baseline_tier == ExecutionTier::kNone) {
 
 3624        new_baseline_tier = ExecutionTier::kNone;
 
 3626      if (old_top_tier == ExecutionTier::kNone) {
 
 3627        new_top_tier = ExecutionTier::kNone;
 
 3630    case WasmCompilationHintStrategy::kLazy:
 
 3631      new_baseline_tier = ExecutionTier::kNone;
 
 3632      new_top_tier = ExecutionTier::kNone;
 
 3634    case WasmCompilationHintStrategy::kEager:
 
 3637    case WasmCompilationHintStrategy::kLazyBaselineEagerTopTier:
 
 3638      new_baseline_tier = ExecutionTier::kNone;
 
 3642  progress = RequiredBaselineTierField::update(progress, new_baseline_tier);
 
 3643  progress = RequiredTopTierField::update(progress, new_top_tier);
 
 3647                                 (old_baseline_tier != ExecutionTier::kNone);
 
 3650void CompilationStateImpl::ApplyPgoInfoToInitialProgress(
 
 3651    ProfileInformation* pgo_info) {
 
 3655  for (
int func_index : pgo_info->executed_functions()) {
 
 3659        RequiredBaselineTierField::decode(progress);
 
 3661    if (old_baseline_tier != ExecutionTier::kNone) 
continue;
 
 3667        RequiredBaselineTierField::update(progress, ExecutionTier::kLiftoff);
 
 3673  for (
int func_index : pgo_info->tiered_up_functions()) {
 
 3677        RequiredBaselineTierField::decode(progress);
 
 3678    ExecutionTier old_top_tier = RequiredTopTierField::decode(progress);
 
 3681    if (old_baseline_tier == ExecutionTier::kTurbofan) 
continue;
 
 3682    if (old_top_tier == ExecutionTier::kTurbofan) 
continue;
 
 3686    progress = RequiredTopTierField::update(progress, ExecutionTier::kTurbofan);
 
 3690void CompilationStateImpl::ApplyPgoInfoLate(ProfileInformation* pgo_info) {
 
 3698  for (
int func_index : pgo_info->executed_functions()) {
 
 3702        RequiredBaselineTierField::decode(progress);
 
 3704    if (old_baseline_tier != ExecutionTier::kNone) 
continue;
 
 3707    ExecutionTier reached_tier = ReachedTierField::decode(progress);
 
 3708    if (reached_tier >= ExecutionTier::kLiftoff) 
continue;
 
 3712        RequiredBaselineTierField::update(progress, ExecutionTier::kLiftoff);
 
 3718    builder.AddTopTierUnit(func_index, ExecutionTier::kLiftoff);
 
 3723  for (
int func_index : pgo_info->tiered_up_functions()) {
 
 3727        RequiredBaselineTierField::decode(progress);
 
 3728    ExecutionTier old_top_tier = RequiredTopTierField::decode(progress);
 
 3731    if (old_baseline_tier == ExecutionTier::kTurbofan) 
continue;
 
 3732    if (old_top_tier == ExecutionTier::kTurbofan) 
continue;
 
 3735    ExecutionTier reached_tier = ReachedTierField::decode(progress);
 
 3736    if (reached_tier == ExecutionTier::kTurbofan) 
continue;
 
 3739    progress = RequiredTopTierField::update(progress, ExecutionTier::kTurbofan);
 
 3740    builder.AddTopTierUnit(func_index, ExecutionTier::kTurbofan);
 
 3745void CompilationStateImpl::InitializeCompilationProgress(
 
 3746    ProfileInformation* pgo_info) {
 
 3752    auto* 
module = native_module_->module();
 
 3757    const ExecutionTierPair default_tiers = GetDefaultTiersPerModule(
 
 3759    const uint8_t default_progress =
 
 3760        RequiredBaselineTierField::encode(default_tiers.baseline_tier) |
 
 3761        RequiredTopTierField::encode(default_tiers.top_tier) |
 
 3762        ReachedTierField::encode(ExecutionTier::kNone);
 
 3765    if (default_tiers.baseline_tier != ExecutionTier::kNone) {
 
 3770    if (
native_module_->enabled_features().has_compilation_hints()) {
 
 3771      size_t num_hints = std::min(module->compilation_hints.size(),
 
 3772                                  size_t{module->num_declared_functions});
 
 3773      for (
size_t hint_idx = 0; hint_idx < num_hints; ++hint_idx) {
 
 3774        const auto& hint = 
module->compilation_hints[hint_idx];
 
 3775        ApplyCompilationHintToInitialProgress(hint, hint_idx);
 
 3782            v8_flags.wasm_eager_tier_up_function >= 0 &&
 
 3783            static_cast<uint32_t
>(
v8_flags.wasm_eager_tier_up_function) >=
 
 3784                module->num_imported_functions &&
 
 3785            static_cast<uint32_t
>(
v8_flags.wasm_eager_tier_up_function) <
 
 3786                module->functions.size())) {
 
 3788          v8_flags.wasm_eager_tier_up_function - 
module->num_imported_functions;
 
 3789      WasmCompilationHint hint{WasmCompilationHintStrategy::kEager,
 
 3790                               WasmCompilationHintTier::kOptimized,
 
 3791                               WasmCompilationHintTier::kOptimized};
 
 3792      ApplyCompilationHintToInitialProgress(hint, func_idx);
 
 3797  if (pgo_info) ApplyPgoInfoToInitialProgress(pgo_info);
 
 3801  TriggerOutstandingCallbacks();
 
 3804void CompilationStateImpl::AddCompilationUnitInternal(
 
 3805    CompilationUnitBuilder* builder, 
int function_index,
 
 3806    uint8_t function_progress) {
 
 3808      CompilationStateImpl::RequiredBaselineTierField::decode(
 
 3811      CompilationStateImpl::RequiredTopTierField::decode(function_progress);
 
 3813      CompilationStateImpl::ReachedTierField::decode(function_progress);
 
 3815  if (reached_tier < required_baseline_tier) {
 
 3816    builder->AddBaselineUnit(function_index, required_baseline_tier);
 
 3818  if (reached_tier < required_top_tier &&
 
 3819      required_baseline_tier != required_top_tier) {
 
 3820    builder->AddTopTierUnit(function_index, required_top_tier);
 
 3824void CompilationStateImpl::InitializeCompilationUnits(
 
 3825    std::unique_ptr<CompilationUnitBuilder> builder) {
 
 3833        int func_index = 
offset + 
static_cast<int>(
i);
 
 3834        AddCompilationUnitInternal(builder.get(), func_index,
 
 3842void CompilationStateImpl::AddCompilationUnit(CompilationUnitBuilder* builder,
 
 3845  int progress_index = func_index - 
offset;
 
 3846  uint8_t function_progress = 0;
 
 3857  AddCompilationUnitInternal(builder, func_index, function_progress);
 
 3860void CompilationStateImpl::InitializeCompilationProgressAfterDeserialization(
 
 3861    base::Vector<const int> lazy_functions,
 
 3862    base::Vector<const int> eager_functions) {
 
 3863  TRACE_EVENT2(
"v8.wasm", 
"wasm.CompilationAfterDeserialization",
 
 3864               "num_lazy_functions", lazy_functions.size(),
 
 3865               "num_eager_functions", eager_functions.size());
 
 3866  std::optional<TimedHistogramScope> lazy_compile_time_scope;
 
 3867  if (base::TimeTicks::IsHighResolution()) {
 
 3868    lazy_compile_time_scope.emplace(
 
 3869        counters()->wasm_compile_after_deserialize());
 
 3872  auto* 
module = native_module_->module();
 
 3879    constexpr uint8_t kProgressAfterTurbofanDeserialization =
 
 3880        RequiredBaselineTierField::encode(ExecutionTier::kLiftoff) |
 
 3881        RequiredTopTierField::encode(ExecutionTier::kTurbofan) |
 
 3882        ReachedTierField::encode(ExecutionTier::kTurbofan);
 
 3884                                 kProgressAfterTurbofanDeserialization);
 
 3887    constexpr uint8_t kProgressForLazyFunctions =
 
 3888        RequiredBaselineTierField::encode(ExecutionTier::kNone) |
 
 3889        RequiredTopTierField::encode(ExecutionTier::kNone) |
 
 3890        ReachedTierField::encode(ExecutionTier::kNone);
 
 3891    for (
auto func_index : lazy_functions) {
 
 3893          kProgressForLazyFunctions;
 
 3897    constexpr bool kNotLazy = 
false;
 
 3898    ExecutionTierPair default_tiers = GetDefaultTiersPerModule(
 
 3900    uint8_t progress_for_eager_functions =
 
 3901        RequiredBaselineTierField::encode(default_tiers.baseline_tier) |
 
 3902        RequiredTopTierField::encode(default_tiers.top_tier) |
 
 3903        ReachedTierField::encode(ExecutionTier::kNone);
 
 3904    for (
auto func_index : eager_functions) {
 
 3908          kProgressAfterTurbofanDeserialization);
 
 3910          progress_for_eager_functions;
 
 3912    DCHECK_NE(ExecutionTier::kNone, default_tiers.baseline_tier);
 
 3917    if (eager_functions.empty() || 
v8_flags.wasm_lazy_compilation) {
 
 3921  auto builder = std::make_unique<CompilationUnitBuilder>(
native_module_);
 
 3922  InitializeCompilationUnits(std::move(builder));
 
 3923  if (!
v8_flags.wasm_lazy_compilation) {
 
 3924    WaitForCompilationEvent(CompilationEvent::kFinishedBaselineCompilation);
 
 3928void CompilationStateImpl::AddCallback(
 
 3929    std::unique_ptr<CompilationEventCallback> 
callback) {
 
 3932  for (
auto event : {CompilationEvent::kFinishedBaselineCompilation,
 
 3933                     CompilationEvent::kFailedCompilation}) {
 
 3938  constexpr base::EnumSet<CompilationEvent> kFinalEvents{
 
 3939      CompilationEvent::kFailedCompilation};
 
 3945void CompilationStateImpl::CommitCompilationUnits(
 
 3946    base::Vector<WasmCompilationUnit> baseline_units,
 
 3947    base::Vector<WasmCompilationUnit> top_tier_units) {
 
 3948  base::MutexGuard guard{&
mutex_};
 
 3949  if (!baseline_units.empty() || !top_tier_units.empty()) {
 
 3953  if (!baseline_units.empty()) {
 
 3957  if (!top_tier_units.empty()) {
 
 3963void CompilationStateImpl::CommitTopTierCompilationUnit(
 
 3964    WasmCompilationUnit 
unit) {
 
 3965  CommitCompilationUnits({}, {&
unit, 1});
 
 3968void CompilationStateImpl::AddTopTierPriorityCompilationUnit(
 
 3977CompilationUnitQueues::Queue* CompilationStateImpl::GetQueueForCompileTask(
 
 3982std::optional<WasmCompilationUnit> CompilationStateImpl::GetNextCompilationUnit(
 
 3983    CompilationUnitQueues::Queue* queue, CompilationTier tier) {
 
 3987void CompilationStateImpl::OnFinishedUnits(
 
 3988    base::Vector<WasmCode*> code_vector) {
 
 3990               "wasm.OnFinishedUnits", 
"units", code_vector.size());
 
 3996  static_assert(ExecutionTier::kNone < ExecutionTier::kLiftoff &&
 
 3997                    ExecutionTier::kLiftoff < ExecutionTier::kTurbofan,
 
 3998                "Assume an order on execution tiers");
 
 4005  bool has_top_tier_code = 
false;
 
 4007  for (
size_t i = 0; 
i < code_vector.
size(); 
i++) {
 
 4008    WasmCode* code = code_vector[
i];
 
 4012    has_top_tier_code |= code->tier() == ExecutionTier::kTurbofan;
 
 4017      DCHECK_EQ(code->tier(), ExecutionTier::kTurbofan);
 
 4021      DCHECK_NE(code->tier(), ExecutionTier::kNone);
 
 4031          RequiredBaselineTierField::decode(function_progress);
 
 4032      ExecutionTier reached_tier = ReachedTierField::decode(function_progress);
 
 4035      if (reached_tier < required_baseline_tier &&
 
 4036          required_baseline_tier <= code->tier()) {
 
 4040      if (code->tier() == ExecutionTier::kTurbofan) {
 
 4045      if (code->tier() > reached_tier) {
 
 4061      const bool is_liftoff = code->tier() == ExecutionTier::kLiftoff;
 
 4062      auto published_code_is_liftoff = [
this](
int index) {
 
 4064        if (code == 
nullptr) 
return false;
 
 4065        return code->is_liftoff();
 
 4068          (is_liftoff || published_code_is_liftoff(code->index()))) {
 
 4072        DCHECK_LE(required_baseline_tier, ExecutionTier::kLiftoff);
 
 4087  TriggerOutstandingCallbacks();
 
 4091class TriggerCodeCachingAfterTimeoutTask : 
public v8::Task {
 
 4093  explicit TriggerCodeCachingAfterTimeoutTask(
 
 4094      std::weak_ptr<NativeModule> native_module)
 
 4097  void Run()
 override {
 
 4098    if (std::shared_ptr<NativeModule> native_module = 
native_module_.lock()) {
 
 4099      Impl(native_module->compilation_state())->TriggerCachingAfterTimeout();
 
 4108void CompilationStateImpl::TriggerOutstandingCallbacks() {
 
 4111  base::EnumSet<CompilationEvent> triggered_events;
 
 4113    triggered_events.Add(CompilationEvent::kFinishedBaselineCompilation);
 
 4118  if (
v8_flags.wasm_dynamic_tiering &&
 
 4119      static_cast<size_t>(
v8_flags.wasm_caching_threshold) <=
 
 4126        static_cast<size_t>(
v8_flags.wasm_caching_hard_threshold) <=
 
 4128      triggered_events.Add(CompilationEvent::kFinishedCompilationChunk);
 
 4134      V8::GetCurrentPlatform()->PostDelayedTaskOnWorkerThread(
 
 4135          TaskPriority::kUserVisible,
 
 4136          std::make_unique<TriggerCodeCachingAfterTimeoutTask>(
 
 4138          1e-3 * 
v8_flags.wasm_caching_timeout_ms);
 
 4149        base::EnumSet<CompilationEvent>({CompilationEvent::kFailedCompilation});
 
 4152  TriggerCallbacks(triggered_events);
 
 4155void CompilationStateImpl::TriggerCallbacks(
 
 4156    base::EnumSet<CompilationEvent> events) {
 
 4157  if (events.empty()) 
return;
 
 4165       {std::make_pair(CompilationEvent::kFailedCompilation,
 
 4166                       "wasm.CompilationFailed"),
 
 4167        std::make_pair(CompilationEvent::kFinishedBaselineCompilation,
 
 4168                       "wasm.BaselineFinished"),
 
 4169        std::make_pair(CompilationEvent::kFinishedCompilationChunk,
 
 4170                       "wasm.CompilationChunkFinished")}) {
 
 4171    if (!events.contains(event.first)) 
continue;
 
 4180    auto new_end = std::remove_if(
 
 4182          return callback->release_after_final_event();
 
 4188void CompilationStateImpl::TriggerCachingAfterTimeout() {
 
 4197  base::TimeTicks caching_time =
 
 4199      base::TimeDelta::FromMilliseconds(
v8_flags.wasm_caching_timeout_ms);
 
 4200  base::TimeDelta time_until_caching = caching_time - base::TimeTicks::Now();
 
 4203  if (time_until_caching >= base::TimeDelta::FromMicroseconds(500)) {
 
 4205        static_cast<int>(time_until_caching.InMillisecondsRoundedUp());
 
 4207    V8::GetCurrentPlatform()->PostDelayedTaskOnWorkerThread(
 
 4208        TaskPriority::kUserVisible,
 
 4209        std::make_unique<TriggerCodeCachingAfterTimeoutTask>(
 
 4215  TriggerCallbacks({CompilationEvent::kFinishedCompilationChunk});
 
 4220void CompilationStateImpl::OnCompilationStopped(
 
 4221    WasmDetectedFeatures detected_features) {
 
 4222  WasmDetectedFeatures new_detected_features =
 
 4223      UpdateDetectedFeatures(detected_features);
 
 4224  if (new_detected_features.empty()) 
return;
 
 4231         (new_detected_features -
 
 4232          WasmDetectedFeatures{{WasmDetectedFeature::stringref,
 
 4233                                WasmDetectedFeature::imported_strings_utf8,
 
 4234                                WasmDetectedFeature::imported_strings}})
 
 4240WasmDetectedFeatures CompilationStateImpl::UpdateDetectedFeatures(
 
 4241    WasmDetectedFeatures detected_features) {
 
 4242  WasmDetectedFeatures old_features =
 
 4245      old_features, old_features | detected_features,
 
 4246      std::memory_order_relaxed)) {
 
 4249  return detected_features - old_features;
 
 4252void CompilationStateImpl::PublishCompilationResults(
 
 4253    std::vector<UnpublishedWasmCode> unpublished_code) {
 
 4254  if (unpublished_code.empty()) 
return;
 
 4258  for (
const auto& [code, assumptions] : unpublished_code) {
 
 4259    int func_index = code->index();
 
 4264  PublishCode(base::VectorOf(unpublished_code));
 
 4267std::vector<WasmCode*> CompilationStateImpl::PublishCode(
 
 4268    base::Vector<UnpublishedWasmCode> code) {
 
 4269  WasmCodeRefScope code_ref_scope;
 
 4270  std::vector<WasmCode*> published_code =
 
 4277  OnFinishedUnits(base::VectorOf(published_code));
 
 4278  return published_code;
 
 4281void CompilationStateImpl::SchedulePublishCompilationResults(
 
 4282    std::vector<UnpublishedWasmCode> unpublished_code, CompilationTier tier) {
 
 4285    base::MutexGuard guard(&state.mutex_);
 
 4286    if (state.publisher_running_) {
 
 4288      state.publish_queue_.reserve(state.publish_queue_.size() +
 
 4289                                   unpublished_code.size());
 
 4290      for (
auto& c : unpublished_code) {
 
 4291        state.publish_queue_.emplace_back(std::move(c));
 
 4295    state.publisher_running_ = 
true;
 
 4298    PublishCompilationResults(std::move(unpublished_code));
 
 4299    unpublished_code.clear();
 
 4302    base::MutexGuard guard(&state.mutex_);
 
 4303    DCHECK(state.publisher_running_);
 
 4304    if (state.publish_queue_.empty()) {
 
 4305      state.publisher_running_ = 
false;
 
 4308    unpublished_code.swap(state.publish_queue_);
 
 4312size_t CompilationStateImpl::NumOutstandingCompilations(
 
 4313    CompilationTier tier)
 const {
 
 4317void CompilationStateImpl::SetError() {
 
 4324  TriggerOutstandingCallbacks();
 
 4328void CompilationStateImpl::WaitForCompilationEvent(
 
 4330  switch (expect_event) {
 
 4331    case CompilationEvent::kFinishedBaselineCompilation:
 
 4339  base::EnumSet<CompilationEvent> events{expect_event,
 
 4340                                         CompilationEvent::kFailedCompilation};
 
 4346void CompilationStateImpl::TierUpAllFunctions() {
 
 4348  uint32_t num_wasm_functions = 
module->num_declared_functions;
 
 4349  WasmCodeRefScope code_ref_scope;
 
 4351  for (uint32_t 
i = 0; 
i < num_wasm_functions; ++
i) {
 
 4352    int func_index = 
module->num_imported_functions + i;
 
 4354    if (!code || !code->is_turbofan()) {
 
 4355      builder.AddTopTierUnit(func_index, ExecutionTier::kTurbofan);
 
 4362    bool ShouldYield()
 override { 
return false; }
 
 4363    bool IsJoiningThread()
 const override { 
return true; }
 
 4364    void NotifyConcurrencyIncrease()
 override { 
UNIMPLEMENTED(); }
 
 4365    uint8_t GetTaskId()
 override { 
return kMainTaskId; }
 
 4368  DummyDelegate delegate;
 
 4370                          CompilationTier::kTopTier);
 
 4374  for (uint32_t 
i = 0; 
i < num_wasm_functions; ++
i) {
 
 4375    uint32_t func_index = 
module->num_imported_functions + i;
 
 4377    if (!code || !code->is_turbofan()) {
 
 4380                                             wasm::ExecutionTier::kTurbofan);
 
 4390                                      int expected_arity, 
Suspend suspend) {
 
 
 4409#undef TRACE_STREAMING 
#define SBXCHECK_LE(lhs, rhs)
#define SBXCHECK_EQ(lhs, rhs)
#define SLOW_DCHECK(condition)
virtual bool ShouldYield()=0
virtual void NotifyConcurrencyIncrease()=0
void PostTask(std::unique_ptr< Task > task, const SourceLocation &location=SourceLocation::Current())
constexpr bool contains_all(EnumSet set) const
constexpr bool contains(E element) const
Hasher & AddRange(Iterator first, Iterator last)
constexpr size_t hash() const
constexpr size_t size() const
Vector< T > as_vector() const
static OwnedVector< T > NewForOverwrite(size_t size)
int64_t InMicroseconds() const
static bool IsHighResolution()
Vector< T > SubVector(size_t from, size_t to) const
constexpr size_t size() const
Vector< T > SubVectorFrom(size_t from) const
constexpr T * data() const
void OnAfterCompile(DirectHandle< Script > script)
V8_WARN_UNUSED_RESULT MaybeHandle< String > NewStringFromUtf8(base::Vector< const char > str, AllocationType allocation=AllocationType::kYoung)
static void Destroy(Address *location)
IndirectHandle< Object > Create(Tagged< Object > value)
GlobalHandles * global_handles() const
const std::shared_ptr< Counters > & async_counters()
void CountUsage(v8::Isolate::UseCounterFeature feature)
Tagged< Context > context() const
v8::internal::Factory * factory()
const std::shared_ptr< metrics::Recorder > & metrics_recorder()
V8_INLINE DirectHandle< T > ToHandleChecked() const
static V8_EXPORT_PRIVATE v8::Platform * GetCurrentPlatform()
static V8_EXPORT_PRIVATE DirectHandle< WasmModuleObject > New(Isolate *isolate, std::shared_ptr< wasm::NativeModule > native_module, DirectHandle< Script > script)
CompilationStateCallback(AsyncCompileJob *job)
void call(CompilationEvent event) override
virtual ~CompileStep()=default
virtual void RunInBackground(AsyncCompileJob *)
void Run(AsyncCompileJob *job, bool on_foreground)
virtual void RunInForeground(AsyncCompileJob *)
void ResetPendingForegroundTask() const
CompileTask(AsyncCompileJob *job, bool on_foreground)
void RunInBackground(AsyncCompileJob *job) override
DecodeModule(Counters *counters, std::shared_ptr< metrics::Recorder > metrics_recorder)
std::shared_ptr< metrics::Recorder > metrics_recorder_
Counters *const counters_
void RunInForeground(AsyncCompileJob *job) override
FinishCompilation(std::shared_ptr< NativeModule > cached_native_module)
std::shared_ptr< NativeModule > cached_native_module_
void RunInForeground(AsyncCompileJob *job) override
const size_t code_size_estimate_
const bool start_compilation_
void RunInForeground(AsyncCompileJob *job) override
PrepareAndStartCompile(std::shared_ptr< const WasmModule > module, bool start_compilation, bool lazy_functions_are_validated, size_t code_size_estimate)
const std::shared_ptr< const WasmModule > module_
const bool lazy_functions_are_validated_
CompileTimeImports compile_imports_
const char *const api_method_name_
Isolate * isolate() const
V8_WARN_UNUSED_RESULT bool DecrementAndCheckFinisherCount()
const WasmEnabledFeatures enabled_features_
void NextStep(Args &&... args)
void FinishCompile(bool is_after_cache_hit)
CancelableTaskManager background_task_manager_
IndirectHandle< WasmModuleObject > module_object_
const std::shared_ptr< CompilationResultResolver > resolver_
WasmDetectedFeatures detected_features_
IndirectHandle< NativeContext > incumbent_context_
std::shared_ptr< StreamingDecoder > CreateStreamingDecoder()
v8::metrics::Recorder::ContextId context_id_
std::shared_ptr< v8::TaskRunner > foreground_task_runner_
IndirectHandle< NativeContext > native_context_
std::shared_ptr< StreamingDecoder > stream_
std::shared_ptr< NativeModule > native_module_
void FinishSuccessfully()
v8::metrics::Recorder::ContextId context_id() const
void CancelPendingForegroundTask()
void StartBackgroundTask()
void StartForegroundTask()
base::TimeTicks start_time_
void DoImmediately(Args &&... args)
std::atomic< int32_t > outstanding_finishers_
const int compilation_id_
bool GetOrCreateNativeModule(std::shared_ptr< const WasmModule > module, size_t code_size_estimate)
void ExecuteForegroundTaskImmediately()
v8::metrics::WasmModuleDecoded metrics_event_
void DoAsync(Args &&... args)
void CreateNativeModule(std::shared_ptr< const WasmModule > module, size_t code_size_estimate)
CompileTask * pending_foreground_task_
base::OwnedVector< const uint8_t > bytes_copy_
void PrepareRuntimeObjects()
std::unique_ptr< CompileStep > step_
void DoSync(Args &&... args)
ModuleWireBytes wire_bytes_
UseExistingForegroundTask
void OnFinishedStream(base::OwnedVector< const uint8_t > bytes, bool after_error) override
void OnFinishedChunk() override
bool before_code_section_
base::Hasher prefix_hasher_
std::unique_ptr< JobHandle > validate_functions_job_handle_
bool ProcessCodeSectionHeader(int num_functions, uint32_t functions_mismatch_error_offset, std::shared_ptr< WireBytesStorage >, int code_section_start, int code_section_length) override
AsyncStreamingProcessor(AsyncCompileJob *job)
bool ProcessFunctionBody(base::Vector< const uint8_t > bytes, uint32_t offset) override
bool ProcessSection(SectionCode section_code, base::Vector< const uint8_t > bytes, uint32_t offset) override
ValidateFunctionsStreamingJobData validate_functions_job_data_
bool Deserialize(base::Vector< const uint8_t > wire_bytes, base::Vector< const uint8_t > module_bytes) override
std::unique_ptr< CompilationUnitBuilder > compilation_unit_builder_
void CommitCompilationUnits()
bool ProcessModuleHeader(base::Vector< const uint8_t > bytes) override
bool is_megamorphic() const
int call_count(int i) const
bool has_non_inlineable_targets() const
int function_index(int i) const
bool has_string_constants(base::Vector< const uint8_t > name) const
bool contains(CompileTimeImport imp) const
void CompileFailed(const WasmError &error)
V8_WARN_UNUSED_RESULT DirectHandle< JSObject > Reify()
void AddCall(int target, int count)
void AddCallRefCandidate(Tagged< WasmFuncRef > funcref, int count)
const Tagged< WasmTrustedInstanceData > instance_data_
void AddCallIndirectCandidate(Tagged< Object > target_truncated_obj, int count)
bool HasTargetCached(int target)
void set_has_non_inlineable_targets()
FeedbackMaker(Isolate *const isolate, Tagged< WasmTrustedInstanceData > trusted_instance_data, int func_index, int num_calls)
base::OwnedVector< CallSiteFeedback > GetResult() &&
base::OwnedVector< CallSiteFeedback > result_
void AddResult(CallSiteFeedback feedback)
std::array< int, kMaxPolymorphism > targets_cache_
std::array< int, kMaxPolymorphism > counts_cache_
const int num_imported_functions_
WasmModule * module() const
void DecodeSection(SectionCode section_code, base::Vector< const uint8_t > bytes, uint32_t offset)
void StartCodeSection(WireBytesRef section_bytes)
const std::shared_ptr< WasmModule > & shared_module() const
ModuleResult FinishDecoding()
void DecodeModuleHeader(base::Vector< const uint8_t > bytes)
static size_t IdentifyUnknownSection(ModuleDecoder *decoder, base::Vector< const uint8_t > bytes, uint32_t offset, SectionCode *result)
void DecodeFunctionBody(uint32_t index, uint32_t size, uint32_t offset)
bool CheckFunctionsCount(uint32_t functions_count, uint32_t error_offset)
static size_t PrefixHash(base::Vector< const uint8_t > wire_bytes)
CompilationState * compilation_state() const
uint32_t num_functions() const
const WasmModule * module() const
base::Vector< const uint8_t > wire_bytes() const
bool HasCodeWithTier(uint32_t index, ExecutionTier tier) const
WasmCode * PublishCode(UnpublishedWasmCode)
DebugState IsInDebugState() const
bool lazy_compile_frozen() const
V8_WARN_UNUSED_RESULT UnpublishedWasmCode AddCompiledCode(WasmCompilationResult &)
WasmEnabledFeatures enabled_features() const
uint32_t num_imported_functions() const
const T & value() const &
static std::unique_ptr< StreamingDecoder > CreateAsyncStreamingDecoder(std::unique_ptr< StreamingProcessor > processor)
const Tagged< WasmTrustedInstanceData > instance_data_
void EnqueueCallees(base::Vector< CallSiteFeedback > feedback)
std::unordered_map< uint32_t, FunctionTypeFeedback > & feedback_for_function_
TransitiveTypeFeedbackProcessor(Isolate *isolate, Tagged< WasmTrustedInstanceData > trusted_instance_data, int func_index)
DisallowGarbageCollection no_gc_scope_
static void Process(Isolate *isolate, Tagged< WasmTrustedInstanceData > trusted_instance_data, int func_index)
const WasmModule *const module_
~TransitiveTypeFeedbackProcessor()
base::MutexGuard mutex_guard
const WasmEnabledFeatures enabled_features_
void Run(JobDelegate *delegate) override
ValidateFunctionsStreamingJob(const WasmModule *module, WasmEnabledFeatures enabled_features, ValidateFunctionsStreamingJobData *data)
ValidateFunctionsStreamingJobData * data_
const WasmModule *const module_
size_t GetMaxConcurrency(size_t worker_count) const override
static size_t EstimateNativeModuleCodeSize(const WasmModule *)
Address GetEntrypointWithoutSignatureCheck(WasmCodePointer index) const
std::shared_ptr< NativeModule > MaybeGetNativeModule(ModuleOrigin origin, base::Vector< const uint8_t > wire_bytes, const CompileTimeImports &compile_imports, Isolate *isolate)
void LogCode(base::Vector< WasmCode * >)
AccountingAllocator * allocator()
void LogOutstandingCodesForIsolate(Isolate *)
std::unique_ptr< AsyncCompileJob > RemoveCompileJob(AsyncCompileJob *job)
DirectHandle< Script > GetOrCreateScript(Isolate *, const std::shared_ptr< NativeModule > &, base::Vector< const char > source_url)
void StreamingCompilationFailed(size_t prefix_hash, const CompileTimeImports &compile_imports)
std::shared_ptr< NativeModule > NewNativeModule(Isolate *isolate, WasmEnabledFeatures enabled_features, WasmDetectedFeatures detected_features, CompileTimeImports compile_imports, std::shared_ptr< const WasmModule > module, size_t code_size_estimate)
std::shared_ptr< NativeModule > UpdateNativeModuleCache(bool has_error, std::shared_ptr< NativeModule > native_module, Isolate *isolate)
WasmCode * CompileWasmImportCallWrapper(Isolate *isolate, ImportCallKind kind, const CanonicalSig *sig, CanonicalTypeIndex sig_index, bool source_positions, int expected_arity, Suspend suspend)
uint32_t end_offset() const
base::Vector< const DirectHandle< Object > > args
v8::Global< v8::Promise::Resolver > resolver_
SourcePositionTable * source_positions
ZoneVector< RpoNumber > & result
size_t bytes_since_last_chunk_
std::shared_ptr< NativeModule > native_module_
base::ElapsedTimer timer_
#define CHECK_SIG(import_name, kSigName, kEnumName)
std::atomic< size_t > num_units_[CompilationTier::kNumTiers]
v8::metrics::Recorder::ContextId context_id_
const int num_imported_functions_
std::priority_queue< TopTierPriorityUnit > top_tier_priority_units
base::TimeTicks last_top_tier_compilation_timestamp_
std::unique_ptr< std::atomic< bool >[]> top_tier_compiled_
std::atomic< bool > compile_failed_
PublishState publish_state_[CompilationTier::kNumTiers]
std::shared_ptr< OperationsBarrier > engine_barrier_
base::Mutex queues_mutex_
std::atomic< size_t > num_priority_units_
const CompileMode compile_mode_
static constexpr size_t kBigUnitsLimit
std::shared_ptr< metrics::Recorder > metrics_recorder_
int outstanding_baseline_units_
std::vector< uint8_t > compilation_progress_
const CompilationTier tier_
std::unique_ptr< JobHandle > top_tier_compile_job_
#define TRACE_COMPILE(...)
std::shared_ptr< WireBytesStorage > wire_bytes_storage_
base::TimeTicks start_time_
std::unique_ptr< JobHandle > baseline_compile_job_
std::atomic< WasmDetectedFeatures > detected_features_
CompilationUnitQueues compilation_unit_queues_
std::atomic< bool > compile_cancelled_
BigUnitsQueue big_units_queue_
std::weak_ptr< NativeModule > const native_module_weak_
const std::shared_ptr< Counters > async_counters_
std::vector< std::unique_ptr< QueueImpl > > queues_
ExecutionTier baseline_tier
std::vector< WasmCompilationUnit > baseline_units_
base::Mutex callbacks_mutex_
std::atomic< bool > has_units[CompilationTier::kNumTiers]
#define RETURN_ERROR(module_name_string, import_name)
const int num_declared_functions_
#define TRACE_STREAMING(...)
std::vector< std::unique_ptr< CompilationEventCallback > > callbacks_
std::vector< WasmCompilationUnit > tiering_units_
std::priority_queue< BigUnit > units[CompilationTier::kNumTiers]
static constexpr int kInvalidCompilationID
std::atomic< int > next_queue_to_add
base::EnumSet< CompilationEvent > finished_events_
std::vector< UnpublishedWasmCode > publish_queue_
std::atomic< int > publish_limit
#define CHECK_USE_COUNTER(feat,...)
const base::Vector< const uint8_t > wire_bytes_
const WasmEnabledFeatures enabled_features_
v8::JobDelegate JobDelegate
constexpr bool IsPowerOfTwo(T value)
constexpr Vector< T > VectorOf(T *start, size_t size)
LockGuard< Mutex > MutexGuard
template const Signature< wasm::ValueType > bool
@ kFinishedBaselineCompilation
@ kFinishedCompilationChunk
V8_EXPORT_PRIVATE WasmCodePointerTable * GetProcessWideWasmCodePointerTable()
void TierUpNowForTesting(Isolate *isolate, Tagged< WasmTrustedInstanceData > trusted_instance_data, int func_index)
WasmImportWrapperCache * GetWasmImportWrapperCache()
constexpr IndependentHeapType kWasmRefExtern
void TriggerTierUp(Isolate *isolate, Tagged< WasmTrustedInstanceData > trusted_instance_data, int func_index)
void TierUpAllForTesting(Isolate *isolate, Tagged< WasmTrustedInstanceData > trusted_instance_data)
void InitializeCompilationForTesting(NativeModule *native_module)
bool is_asmjs_module(const WasmModule *module)
constexpr IndependentHeapType kWasmExternRef
constexpr IndependentValueType kWasmI32
ModuleResult DecodeWasmModule(WasmEnabledFeatures enabled_features, base::Vector< const uint8_t > wire_bytes, bool validate_functions, ModuleOrigin origin, Counters *counters, std::shared_ptr< metrics::Recorder > metrics_recorder, v8::metrics::Recorder::ContextId context_id, DecodingMethod decoding_method, WasmDetectedFeatures *detected_features)
WasmCode * CompileImportWrapperForTest(Isolate *isolate, NativeModule *native_module, ImportCallKind kind, const CanonicalSig *sig, CanonicalTypeIndex type_index, int expected_arity, Suspend suspend)
void ThrowLazyCompilationError(Isolate *isolate, const NativeModule *native_module, int func_index)
MaybeDirectHandle< WasmModuleObject > DeserializeNativeModule(Isolate *isolate, base::Vector< const uint8_t > data, base::Vector< const uint8_t > wire_bytes_vec, const CompileTimeImports &compile_imports, base::Vector< const char > source_url)
std::shared_ptr< NativeModule > CompileToNativeModule(Isolate *isolate, WasmEnabledFeatures enabled_features, WasmDetectedFeatures detected_features, CompileTimeImports compile_imports, ErrorThrower *thrower, std::shared_ptr< const WasmModule > module, base::OwnedVector< const uint8_t > wire_bytes, int compilation_id, v8::metrics::Recorder::ContextId context_id, ProfileInformation *pgo_info)
WasmError ValidateAndSetBuiltinImports(const WasmModule *module, base::Vector< const uint8_t > wire_bytes, const CompileTimeImports &imports, WasmDetectedFeatures *detected)
size_t ContentSize(const std::vector< T > &vector)
constexpr int kMaxPolymorphism
WasmError ValidateFunctions(const WasmModule *module, WasmEnabledFeatures enabled_features, base::Vector< const uint8_t > wire_bytes, std::function< bool(int)> filter, WasmDetectedFeatures *detected_features_out)
DecodeResult ValidateFunctionBody(Zone *zone, WasmEnabledFeatures enabled, const WasmModule *module, WasmDetectedFeatures *detected, const FunctionBody &body)
WasmEngine * GetWasmEngine()
int declared_function_index(const WasmModule *module, int func_index)
std::unique_ptr< ProfileInformation > LoadProfileFromFile(const WasmModule *module, base::Vector< const uint8_t > wire_bytes)
@ kLazyBaselineEagerTopTier
bool IsCrossInstanceCall(Tagged< Object > obj, Isolate *const isolate)
void PublishDetectedFeatures(WasmDetectedFeatures detected_features, Isolate *isolate, bool is_initial_compilation)
bool CompileLazy(Isolate *isolate, Tagged< WasmTrustedInstanceData > trusted_instance_data, int func_index)
WasmError GetWasmErrorWithName(base::Vector< const uint8_t > wire_bytes, int func_index, const WasmModule *module, WasmError error)
V8_INLINE IndirectHandle< T > handle(Tagged< T > object, Isolate *isolate)
void PrintF(const char *format,...)
wasm::WasmModule WasmModule
V8_INLINE constexpr bool IsSmi(TaggedImpl< kRefType, StorageType > obj)
kWasmInternalFunctionIndirectPointerTag kProtectedInstanceDataOffset sig
V8_INLINE constexpr bool operator<(Builtin a, Builtin b)
V8_EXPORT_PRIVATE FlagValues v8_flags
JSArrayBuffer::IsDetachableBit is_shared
wasm::WasmFunction WasmFunction
kInterpreterTrampolineOffset script
#define DCHECK_LE(v1, v2)
#define CHECK_IMPLIES(lhs, rhs)
#define DCHECK_NOT_NULL(val)
#define DCHECK_IMPLIES(v1, v2)
#define DCHECK_NE(v1, v2)
#define DCHECK_GE(v1, v2)
#define DCHECK(condition)
#define DCHECK_LT(v1, v2)
#define DCHECK_EQ(v1, v2)
#define DCHECK_GT(v1, v2)
#define UPDATE_WHEN_CLASS_CHANGES(classname, size)
WasmName GetNameOrNull(WireBytesRef ref) const
base::Vector< const uint8_t > module_bytes() const
base::Vector< const uint8_t > code
base::OwnedVector< Unit > units
void Initialize(int num_declared_functions)
std::atomic< Unit * > end_of_available_units
std::atomic< Unit * > next_available_unit
void UpdateDetectedFeatures(WasmDetectedFeatures new_detected_features)
size_t NumOutstandingUnits() const
std::atomic< bool > found_error
std::atomic< WasmDetectedFeatures > detected_features
void AddUnit(int declared_func_index, base::Vector< const uint8_t > code, JobHandle *job_handle)
bool has_array(ModuleTypeIndex index) const
std::vector< WasmImport > import_table
uint32_t num_declared_functions
const ModuleOrigin origin
uint32_t num_imported_functions
std::vector< WasmGlobal > globals
TypeFeedbackStorage type_feedback
size_t module_size_in_bytes
int64_t wall_clock_duration_in_us
#define TRACE_EVENT0(category_group, name)
#define TRACE_EVENT2(category_group, name, arg1_name, arg1_val, arg2_name, arg2_val)
#define TRACE_DISABLED_BY_DEFAULT(name)
#define TRACE_EVENT1(category_group, name, arg1_name, arg1_val)
#define V8_LIKELY(condition)
#define V8_WARN_UNUSED_RESULT
#define V8_UNLIKELY(condition)
#define FOREACH_WASM_STAGING_FEATURE_FLAG(V)
#define FOREACH_WASM_SHIPPED_FEATURE_FLAG(V)
#define FOREACH_WASM_NON_FLAG_FEATURE(V)
const wasm::WasmModule * module_
#define SELECT_WASM_COUNTER(counters, origin, prefix, suffix)