xref: /third_party/node/deps/v8/src/codegen/compiler.cc (revision 1cb0ef41)
11cb0ef41Sopenharmony_ci// Copyright 2012 the V8 project authors. All rights reserved.
21cb0ef41Sopenharmony_ci// Use of this source code is governed by a BSD-style license that can be
31cb0ef41Sopenharmony_ci// found in the LICENSE file.
41cb0ef41Sopenharmony_ci
51cb0ef41Sopenharmony_ci#include "src/codegen/compiler.h"
61cb0ef41Sopenharmony_ci
71cb0ef41Sopenharmony_ci#include <algorithm>
81cb0ef41Sopenharmony_ci#include <memory>
91cb0ef41Sopenharmony_ci
101cb0ef41Sopenharmony_ci#include "src/api/api-inl.h"
111cb0ef41Sopenharmony_ci#include "src/asmjs/asm-js.h"
121cb0ef41Sopenharmony_ci#include "src/ast/prettyprinter.h"
131cb0ef41Sopenharmony_ci#include "src/ast/scopes.h"
141cb0ef41Sopenharmony_ci#include "src/base/logging.h"
151cb0ef41Sopenharmony_ci#include "src/base/optional.h"
161cb0ef41Sopenharmony_ci#include "src/base/platform/time.h"
171cb0ef41Sopenharmony_ci#include "src/baseline/baseline.h"
181cb0ef41Sopenharmony_ci#include "src/codegen/assembler-inl.h"
191cb0ef41Sopenharmony_ci#include "src/codegen/compilation-cache.h"
201cb0ef41Sopenharmony_ci#include "src/codegen/optimized-compilation-info.h"
211cb0ef41Sopenharmony_ci#include "src/codegen/pending-optimization-table.h"
221cb0ef41Sopenharmony_ci#include "src/codegen/script-details.h"
231cb0ef41Sopenharmony_ci#include "src/codegen/unoptimized-compilation-info.h"
241cb0ef41Sopenharmony_ci#include "src/common/assert-scope.h"
251cb0ef41Sopenharmony_ci#include "src/common/globals.h"
261cb0ef41Sopenharmony_ci#include "src/common/message-template.h"
271cb0ef41Sopenharmony_ci#include "src/compiler-dispatcher/lazy-compile-dispatcher.h"
281cb0ef41Sopenharmony_ci#include "src/compiler-dispatcher/optimizing-compile-dispatcher.h"
291cb0ef41Sopenharmony_ci#include "src/compiler/pipeline.h"
301cb0ef41Sopenharmony_ci#include "src/debug/debug.h"
311cb0ef41Sopenharmony_ci#include "src/debug/liveedit.h"
321cb0ef41Sopenharmony_ci#include "src/diagnostics/code-tracer.h"
331cb0ef41Sopenharmony_ci#include "src/execution/frames-inl.h"
341cb0ef41Sopenharmony_ci#include "src/execution/isolate-inl.h"
351cb0ef41Sopenharmony_ci#include "src/execution/isolate.h"
361cb0ef41Sopenharmony_ci#include "src/execution/local-isolate.h"
371cb0ef41Sopenharmony_ci#include "src/execution/vm-state-inl.h"
381cb0ef41Sopenharmony_ci#include "src/handles/handles.h"
391cb0ef41Sopenharmony_ci#include "src/handles/maybe-handles.h"
401cb0ef41Sopenharmony_ci#include "src/handles/persistent-handles.h"
411cb0ef41Sopenharmony_ci#include "src/heap/heap-inl.h"
421cb0ef41Sopenharmony_ci#include "src/heap/local-factory-inl.h"
431cb0ef41Sopenharmony_ci#include "src/heap/local-heap-inl.h"
441cb0ef41Sopenharmony_ci#include "src/heap/local-heap.h"
451cb0ef41Sopenharmony_ci#include "src/heap/parked-scope.h"
461cb0ef41Sopenharmony_ci#include "src/init/bootstrapper.h"
471cb0ef41Sopenharmony_ci#include "src/interpreter/interpreter.h"
481cb0ef41Sopenharmony_ci#include "src/logging/counters-scopes.h"
491cb0ef41Sopenharmony_ci#include "src/logging/log-inl.h"
501cb0ef41Sopenharmony_ci#include "src/logging/runtime-call-stats-scope.h"
511cb0ef41Sopenharmony_ci#include "src/objects/feedback-cell-inl.h"
521cb0ef41Sopenharmony_ci#include "src/objects/js-function-inl.h"
531cb0ef41Sopenharmony_ci#include "src/objects/map.h"
541cb0ef41Sopenharmony_ci#include "src/objects/object-list-macros.h"
551cb0ef41Sopenharmony_ci#include "src/objects/shared-function-info.h"
561cb0ef41Sopenharmony_ci#include "src/objects/string.h"
571cb0ef41Sopenharmony_ci#include "src/parsing/parse-info.h"
581cb0ef41Sopenharmony_ci#include "src/parsing/parser.h"
591cb0ef41Sopenharmony_ci#include "src/parsing/parsing.h"
601cb0ef41Sopenharmony_ci#include "src/parsing/pending-compilation-error-handler.h"
611cb0ef41Sopenharmony_ci#include "src/parsing/scanner-character-streams.h"
621cb0ef41Sopenharmony_ci#include "src/snapshot/code-serializer.h"
631cb0ef41Sopenharmony_ci#include "src/utils/ostreams.h"
641cb0ef41Sopenharmony_ci#include "src/web-snapshot/web-snapshot.h"
651cb0ef41Sopenharmony_ci#include "src/zone/zone-list-inl.h"  // crbug.com/v8/8816
661cb0ef41Sopenharmony_ci
671cb0ef41Sopenharmony_ci#ifdef V8_ENABLE_MAGLEV
681cb0ef41Sopenharmony_ci#include "src/maglev/maglev-concurrent-dispatcher.h"
691cb0ef41Sopenharmony_ci#include "src/maglev/maglev.h"
701cb0ef41Sopenharmony_ci#endif  // V8_ENABLE_MAGLEV
711cb0ef41Sopenharmony_ci
721cb0ef41Sopenharmony_cinamespace v8 {
731cb0ef41Sopenharmony_cinamespace internal {
741cb0ef41Sopenharmony_ci
751cb0ef41Sopenharmony_cinamespace {
761cb0ef41Sopenharmony_ci
771cb0ef41Sopenharmony_ciconstexpr bool IsOSR(BytecodeOffset osr_offset) { return !osr_offset.IsNone(); }
781cb0ef41Sopenharmony_ci
791cb0ef41Sopenharmony_civoid SetTieringState(JSFunction function, BytecodeOffset osr_offset,
801cb0ef41Sopenharmony_ci                     TieringState value) {
811cb0ef41Sopenharmony_ci  if (IsOSR(osr_offset)) {
821cb0ef41Sopenharmony_ci    function.set_osr_tiering_state(value);
831cb0ef41Sopenharmony_ci  } else {
841cb0ef41Sopenharmony_ci    function.set_tiering_state(value);
851cb0ef41Sopenharmony_ci  }
861cb0ef41Sopenharmony_ci}
871cb0ef41Sopenharmony_ci
881cb0ef41Sopenharmony_civoid ResetTieringState(JSFunction function, BytecodeOffset osr_offset) {
891cb0ef41Sopenharmony_ci  if (function.has_feedback_vector()) {
901cb0ef41Sopenharmony_ci    SetTieringState(function, osr_offset, TieringState::kNone);
911cb0ef41Sopenharmony_ci  }
921cb0ef41Sopenharmony_ci}
931cb0ef41Sopenharmony_ci
941cb0ef41Sopenharmony_civoid ResetProfilerTicks(JSFunction function, BytecodeOffset osr_offset) {
951cb0ef41Sopenharmony_ci  if (!IsOSR(osr_offset)) {
961cb0ef41Sopenharmony_ci    // Reset profiler ticks, the function is no longer considered hot.
971cb0ef41Sopenharmony_ci    // TODO(v8:7700): Update for Maglev tiering.
981cb0ef41Sopenharmony_ci    function.feedback_vector().set_profiler_ticks(0);
991cb0ef41Sopenharmony_ci  }
1001cb0ef41Sopenharmony_ci}
1011cb0ef41Sopenharmony_ci
1021cb0ef41Sopenharmony_ciclass CompilerTracer : public AllStatic {
1031cb0ef41Sopenharmony_ci public:
1041cb0ef41Sopenharmony_ci  static void TracePrepareJob(Isolate* isolate, OptimizedCompilationInfo* info,
1051cb0ef41Sopenharmony_ci                              const char* compiler_name) {
1061cb0ef41Sopenharmony_ci    if (!FLAG_trace_opt || !info->IsOptimizing()) return;
1071cb0ef41Sopenharmony_ci    CodeTracer::Scope scope(isolate->GetCodeTracer());
1081cb0ef41Sopenharmony_ci    PrintTracePrefix(scope, "compiling method", info);
1091cb0ef41Sopenharmony_ci    PrintF(scope.file(), " using %s%s", compiler_name,
1101cb0ef41Sopenharmony_ci           info->is_osr() ? " OSR" : "");
1111cb0ef41Sopenharmony_ci    PrintTraceSuffix(scope);
1121cb0ef41Sopenharmony_ci  }
1131cb0ef41Sopenharmony_ci
1141cb0ef41Sopenharmony_ci  static void TraceStartBaselineCompile(Isolate* isolate,
1151cb0ef41Sopenharmony_ci                                        Handle<SharedFunctionInfo> shared) {
1161cb0ef41Sopenharmony_ci    if (!FLAG_trace_baseline) return;
1171cb0ef41Sopenharmony_ci    CodeTracer::Scope scope(isolate->GetCodeTracer());
1181cb0ef41Sopenharmony_ci    PrintTracePrefix(scope, "compiling method", shared, CodeKind::BASELINE);
1191cb0ef41Sopenharmony_ci    PrintF(scope.file(), " using Sparkplug");
1201cb0ef41Sopenharmony_ci    PrintTraceSuffix(scope);
1211cb0ef41Sopenharmony_ci  }
1221cb0ef41Sopenharmony_ci
1231cb0ef41Sopenharmony_ci  static void TraceOptimizeOSR(Isolate* isolate, Handle<JSFunction> function,
1241cb0ef41Sopenharmony_ci                               BytecodeOffset osr_offset,
1251cb0ef41Sopenharmony_ci                               ConcurrencyMode mode) {
1261cb0ef41Sopenharmony_ci    if (!FLAG_trace_osr) return;
1271cb0ef41Sopenharmony_ci    CodeTracer::Scope scope(isolate->GetCodeTracer());
1281cb0ef41Sopenharmony_ci    PrintF(scope.file(),
1291cb0ef41Sopenharmony_ci           "[OSR - started. function: %s, osr offset: %d, mode: %s]\n",
1301cb0ef41Sopenharmony_ci           function->DebugNameCStr().get(), osr_offset.ToInt(), ToString(mode));
1311cb0ef41Sopenharmony_ci  }
1321cb0ef41Sopenharmony_ci
1331cb0ef41Sopenharmony_ci  static void TraceOptimizeOSRUnavailable(Isolate* isolate,
1341cb0ef41Sopenharmony_ci                                          Handle<JSFunction> function,
1351cb0ef41Sopenharmony_ci                                          BytecodeOffset osr_offset,
1361cb0ef41Sopenharmony_ci                                          ConcurrencyMode mode) {
1371cb0ef41Sopenharmony_ci    if (!FLAG_trace_osr) return;
1381cb0ef41Sopenharmony_ci    CodeTracer::Scope scope(isolate->GetCodeTracer());
1391cb0ef41Sopenharmony_ci    PrintF(scope.file(),
1401cb0ef41Sopenharmony_ci           "[OSR - unavailable (failed or in progress). function: %s, osr "
1411cb0ef41Sopenharmony_ci           "offset: %d, mode: %s]\n",
1421cb0ef41Sopenharmony_ci           function->DebugNameCStr().get(), osr_offset.ToInt(), ToString(mode));
1431cb0ef41Sopenharmony_ci  }
1441cb0ef41Sopenharmony_ci
1451cb0ef41Sopenharmony_ci  static void TraceCompilationStats(Isolate* isolate,
1461cb0ef41Sopenharmony_ci                                    OptimizedCompilationInfo* info,
1471cb0ef41Sopenharmony_ci                                    double ms_creategraph, double ms_optimize,
1481cb0ef41Sopenharmony_ci                                    double ms_codegen) {
1491cb0ef41Sopenharmony_ci    if (!FLAG_trace_opt || !info->IsOptimizing()) return;
1501cb0ef41Sopenharmony_ci    CodeTracer::Scope scope(isolate->GetCodeTracer());
1511cb0ef41Sopenharmony_ci    PrintTracePrefix(scope, "optimizing", info);
1521cb0ef41Sopenharmony_ci    PrintF(scope.file(), " - took %0.3f, %0.3f, %0.3f ms", ms_creategraph,
1531cb0ef41Sopenharmony_ci           ms_optimize, ms_codegen);
1541cb0ef41Sopenharmony_ci    PrintTraceSuffix(scope);
1551cb0ef41Sopenharmony_ci  }
1561cb0ef41Sopenharmony_ci
1571cb0ef41Sopenharmony_ci  static void TraceFinishBaselineCompile(Isolate* isolate,
1581cb0ef41Sopenharmony_ci                                         Handle<SharedFunctionInfo> shared,
1591cb0ef41Sopenharmony_ci                                         double ms_timetaken) {
1601cb0ef41Sopenharmony_ci    if (!FLAG_trace_baseline) return;
1611cb0ef41Sopenharmony_ci    CodeTracer::Scope scope(isolate->GetCodeTracer());
1621cb0ef41Sopenharmony_ci    PrintTracePrefix(scope, "compiling", shared, CodeKind::BASELINE);
1631cb0ef41Sopenharmony_ci    PrintF(scope.file(), " - took %0.3f ms", ms_timetaken);
1641cb0ef41Sopenharmony_ci    PrintTraceSuffix(scope);
1651cb0ef41Sopenharmony_ci  }
1661cb0ef41Sopenharmony_ci
1671cb0ef41Sopenharmony_ci  static void TraceCompletedJob(Isolate* isolate,
1681cb0ef41Sopenharmony_ci                                OptimizedCompilationInfo* info) {
1691cb0ef41Sopenharmony_ci    if (!FLAG_trace_opt) return;
1701cb0ef41Sopenharmony_ci    CodeTracer::Scope scope(isolate->GetCodeTracer());
1711cb0ef41Sopenharmony_ci    PrintTracePrefix(scope, "completed optimizing", info);
1721cb0ef41Sopenharmony_ci    PrintTraceSuffix(scope);
1731cb0ef41Sopenharmony_ci  }
1741cb0ef41Sopenharmony_ci
1751cb0ef41Sopenharmony_ci  static void TraceAbortedJob(Isolate* isolate,
1761cb0ef41Sopenharmony_ci                              OptimizedCompilationInfo* info) {
1771cb0ef41Sopenharmony_ci    if (!FLAG_trace_opt) return;
1781cb0ef41Sopenharmony_ci    CodeTracer::Scope scope(isolate->GetCodeTracer());
1791cb0ef41Sopenharmony_ci    PrintTracePrefix(scope, "aborted optimizing", info);
1801cb0ef41Sopenharmony_ci    PrintF(scope.file(), " because: %s",
1811cb0ef41Sopenharmony_ci           GetBailoutReason(info->bailout_reason()));
1821cb0ef41Sopenharmony_ci    PrintTraceSuffix(scope);
1831cb0ef41Sopenharmony_ci  }
1841cb0ef41Sopenharmony_ci
1851cb0ef41Sopenharmony_ci  static void TraceOptimizedCodeCacheHit(Isolate* isolate,
1861cb0ef41Sopenharmony_ci                                         Handle<JSFunction> function,
1871cb0ef41Sopenharmony_ci                                         BytecodeOffset osr_offset,
1881cb0ef41Sopenharmony_ci                                         CodeKind code_kind) {
1891cb0ef41Sopenharmony_ci    if (!FLAG_trace_opt) return;
1901cb0ef41Sopenharmony_ci    CodeTracer::Scope scope(isolate->GetCodeTracer());
1911cb0ef41Sopenharmony_ci    PrintTracePrefix(scope, "found optimized code for", function, code_kind);
1921cb0ef41Sopenharmony_ci    if (IsOSR(osr_offset)) {
1931cb0ef41Sopenharmony_ci      PrintF(scope.file(), " at OSR bytecode offset %d", osr_offset.ToInt());
1941cb0ef41Sopenharmony_ci    }
1951cb0ef41Sopenharmony_ci    PrintTraceSuffix(scope);
1961cb0ef41Sopenharmony_ci  }
1971cb0ef41Sopenharmony_ci
1981cb0ef41Sopenharmony_ci  static void TraceOptimizeForAlwaysOpt(Isolate* isolate,
1991cb0ef41Sopenharmony_ci                                        Handle<JSFunction> function,
2001cb0ef41Sopenharmony_ci                                        CodeKind code_kind) {
2011cb0ef41Sopenharmony_ci    if (!FLAG_trace_opt) return;
2021cb0ef41Sopenharmony_ci    CodeTracer::Scope scope(isolate->GetCodeTracer());
2031cb0ef41Sopenharmony_ci    PrintTracePrefix(scope, "optimizing", function, code_kind);
2041cb0ef41Sopenharmony_ci    PrintF(scope.file(), " because --always-opt");
2051cb0ef41Sopenharmony_ci    PrintTraceSuffix(scope);
2061cb0ef41Sopenharmony_ci  }
2071cb0ef41Sopenharmony_ci
2081cb0ef41Sopenharmony_ci  static void TraceMarkForAlwaysOpt(Isolate* isolate,
2091cb0ef41Sopenharmony_ci                                    Handle<JSFunction> function) {
2101cb0ef41Sopenharmony_ci    if (!FLAG_trace_opt) return;
2111cb0ef41Sopenharmony_ci    CodeTracer::Scope scope(isolate->GetCodeTracer());
2121cb0ef41Sopenharmony_ci    PrintF(scope.file(), "[marking ");
2131cb0ef41Sopenharmony_ci    function->ShortPrint(scope.file());
2141cb0ef41Sopenharmony_ci    PrintF(scope.file(), " for optimized recompilation because --always-opt");
2151cb0ef41Sopenharmony_ci    PrintF(scope.file(), "]\n");
2161cb0ef41Sopenharmony_ci  }
2171cb0ef41Sopenharmony_ci
2181cb0ef41Sopenharmony_ci private:
2191cb0ef41Sopenharmony_ci  static void PrintTracePrefix(const CodeTracer::Scope& scope,
2201cb0ef41Sopenharmony_ci                               const char* header,
2211cb0ef41Sopenharmony_ci                               OptimizedCompilationInfo* info) {
2221cb0ef41Sopenharmony_ci    PrintTracePrefix(scope, header, info->closure(), info->code_kind());
2231cb0ef41Sopenharmony_ci  }
2241cb0ef41Sopenharmony_ci
2251cb0ef41Sopenharmony_ci  static void PrintTracePrefix(const CodeTracer::Scope& scope,
2261cb0ef41Sopenharmony_ci                               const char* header, Handle<JSFunction> function,
2271cb0ef41Sopenharmony_ci                               CodeKind code_kind) {
2281cb0ef41Sopenharmony_ci    PrintF(scope.file(), "[%s ", header);
2291cb0ef41Sopenharmony_ci    function->ShortPrint(scope.file());
2301cb0ef41Sopenharmony_ci    PrintF(scope.file(), " (target %s)", CodeKindToString(code_kind));
2311cb0ef41Sopenharmony_ci  }
2321cb0ef41Sopenharmony_ci
2331cb0ef41Sopenharmony_ci  static void PrintTracePrefix(const CodeTracer::Scope& scope,
2341cb0ef41Sopenharmony_ci                               const char* header,
2351cb0ef41Sopenharmony_ci                               Handle<SharedFunctionInfo> shared,
2361cb0ef41Sopenharmony_ci                               CodeKind code_kind) {
2371cb0ef41Sopenharmony_ci    PrintF(scope.file(), "[%s ", header);
2381cb0ef41Sopenharmony_ci    shared->ShortPrint(scope.file());
2391cb0ef41Sopenharmony_ci    PrintF(scope.file(), " (target %s)", CodeKindToString(code_kind));
2401cb0ef41Sopenharmony_ci  }
2411cb0ef41Sopenharmony_ci
2421cb0ef41Sopenharmony_ci  static void PrintTraceSuffix(const CodeTracer::Scope& scope) {
2431cb0ef41Sopenharmony_ci    PrintF(scope.file(), "]\n");
2441cb0ef41Sopenharmony_ci  }
2451cb0ef41Sopenharmony_ci};
2461cb0ef41Sopenharmony_ci
2471cb0ef41Sopenharmony_civoid LogFunctionCompilation(Isolate* isolate,
2481cb0ef41Sopenharmony_ci                            CodeEventListener::LogEventsAndTags tag,
2491cb0ef41Sopenharmony_ci                            Handle<Script> script,
2501cb0ef41Sopenharmony_ci                            Handle<SharedFunctionInfo> shared,
2511cb0ef41Sopenharmony_ci                            Handle<FeedbackVector> vector,
2521cb0ef41Sopenharmony_ci                            Handle<AbstractCode> abstract_code, CodeKind kind,
2531cb0ef41Sopenharmony_ci                            double time_taken_ms) {
2541cb0ef41Sopenharmony_ci  DCHECK(!abstract_code.is_null());
2551cb0ef41Sopenharmony_ci  if (V8_EXTERNAL_CODE_SPACE_BOOL) {
2561cb0ef41Sopenharmony_ci    DCHECK_NE(*abstract_code, FromCodeT(*BUILTIN_CODE(isolate, CompileLazy)));
2571cb0ef41Sopenharmony_ci  } else {
2581cb0ef41Sopenharmony_ci    DCHECK(!abstract_code.is_identical_to(BUILTIN_CODE(isolate, CompileLazy)));
2591cb0ef41Sopenharmony_ci  }
2601cb0ef41Sopenharmony_ci
2611cb0ef41Sopenharmony_ci  // Log the code generation. If source information is available include
2621cb0ef41Sopenharmony_ci  // script name and line number. Check explicitly whether logging is
2631cb0ef41Sopenharmony_ci  // enabled as finding the line number is not free.
2641cb0ef41Sopenharmony_ci  if (!isolate->logger()->is_listening_to_code_events() &&
2651cb0ef41Sopenharmony_ci      !isolate->is_profiling() && !FLAG_log_function_events &&
2661cb0ef41Sopenharmony_ci      !isolate->code_event_dispatcher()->IsListeningToCodeEvents()) {
2671cb0ef41Sopenharmony_ci    return;
2681cb0ef41Sopenharmony_ci  }
2691cb0ef41Sopenharmony_ci
2701cb0ef41Sopenharmony_ci  int line_num = Script::GetLineNumber(script, shared->StartPosition()) + 1;
2711cb0ef41Sopenharmony_ci  int column_num = Script::GetColumnNumber(script, shared->StartPosition()) + 1;
2721cb0ef41Sopenharmony_ci  Handle<String> script_name(script->name().IsString()
2731cb0ef41Sopenharmony_ci                                 ? String::cast(script->name())
2741cb0ef41Sopenharmony_ci                                 : ReadOnlyRoots(isolate).empty_string(),
2751cb0ef41Sopenharmony_ci                             isolate);
2761cb0ef41Sopenharmony_ci  CodeEventListener::LogEventsAndTags log_tag =
2771cb0ef41Sopenharmony_ci      Logger::ToNativeByScript(tag, *script);
2781cb0ef41Sopenharmony_ci  PROFILE(isolate, CodeCreateEvent(log_tag, abstract_code, shared, script_name,
2791cb0ef41Sopenharmony_ci                                   line_num, column_num));
2801cb0ef41Sopenharmony_ci  if (!vector.is_null()) {
2811cb0ef41Sopenharmony_ci    LOG(isolate, FeedbackVectorEvent(*vector, *abstract_code));
2821cb0ef41Sopenharmony_ci  }
2831cb0ef41Sopenharmony_ci  if (!FLAG_log_function_events) return;
2841cb0ef41Sopenharmony_ci
2851cb0ef41Sopenharmony_ci  std::string name;
2861cb0ef41Sopenharmony_ci  switch (kind) {
2871cb0ef41Sopenharmony_ci    case CodeKind::INTERPRETED_FUNCTION:
2881cb0ef41Sopenharmony_ci      name = "interpreter";
2891cb0ef41Sopenharmony_ci      break;
2901cb0ef41Sopenharmony_ci    case CodeKind::BASELINE:
2911cb0ef41Sopenharmony_ci      name = "baseline";
2921cb0ef41Sopenharmony_ci      break;
2931cb0ef41Sopenharmony_ci    case CodeKind::TURBOFAN:
2941cb0ef41Sopenharmony_ci      name = "optimize";
2951cb0ef41Sopenharmony_ci      break;
2961cb0ef41Sopenharmony_ci    default:
2971cb0ef41Sopenharmony_ci      UNREACHABLE();
2981cb0ef41Sopenharmony_ci  }
2991cb0ef41Sopenharmony_ci  switch (tag) {
3001cb0ef41Sopenharmony_ci    case CodeEventListener::EVAL_TAG:
3011cb0ef41Sopenharmony_ci      name += "-eval";
3021cb0ef41Sopenharmony_ci      break;
3031cb0ef41Sopenharmony_ci    case CodeEventListener::SCRIPT_TAG:
3041cb0ef41Sopenharmony_ci      break;
3051cb0ef41Sopenharmony_ci    case CodeEventListener::LAZY_COMPILE_TAG:
3061cb0ef41Sopenharmony_ci      name += "-lazy";
3071cb0ef41Sopenharmony_ci      break;
3081cb0ef41Sopenharmony_ci    case CodeEventListener::FUNCTION_TAG:
3091cb0ef41Sopenharmony_ci      break;
3101cb0ef41Sopenharmony_ci    default:
3111cb0ef41Sopenharmony_ci      UNREACHABLE();
3121cb0ef41Sopenharmony_ci  }
3131cb0ef41Sopenharmony_ci
3141cb0ef41Sopenharmony_ci  Handle<String> debug_name = SharedFunctionInfo::DebugName(shared);
3151cb0ef41Sopenharmony_ci  DisallowGarbageCollection no_gc;
3161cb0ef41Sopenharmony_ci  LOG(isolate, FunctionEvent(name.c_str(), script->id(), time_taken_ms,
3171cb0ef41Sopenharmony_ci                             shared->StartPosition(), shared->EndPosition(),
3181cb0ef41Sopenharmony_ci                             *debug_name));
3191cb0ef41Sopenharmony_ci}
3201cb0ef41Sopenharmony_ci
3211cb0ef41Sopenharmony_ci}  // namespace
3221cb0ef41Sopenharmony_ci
3231cb0ef41Sopenharmony_ci// Helper that times a scoped region and records the elapsed time.
3241cb0ef41Sopenharmony_cistruct ScopedTimer {
3251cb0ef41Sopenharmony_ci  explicit ScopedTimer(base::TimeDelta* location) : location_(location) {
3261cb0ef41Sopenharmony_ci    DCHECK_NOT_NULL(location_);
3271cb0ef41Sopenharmony_ci    timer_.Start();
3281cb0ef41Sopenharmony_ci  }
3291cb0ef41Sopenharmony_ci
3301cb0ef41Sopenharmony_ci  ~ScopedTimer() { *location_ += timer_.Elapsed(); }
3311cb0ef41Sopenharmony_ci
3321cb0ef41Sopenharmony_ci  base::ElapsedTimer timer_;
3331cb0ef41Sopenharmony_ci  base::TimeDelta* location_;
3341cb0ef41Sopenharmony_ci};
3351cb0ef41Sopenharmony_ci
3361cb0ef41Sopenharmony_cinamespace {
3371cb0ef41Sopenharmony_ci
3381cb0ef41Sopenharmony_ciScriptOriginOptions OriginOptionsForEval(
3391cb0ef41Sopenharmony_ci    Object script, ParsingWhileDebugging parsing_while_debugging) {
3401cb0ef41Sopenharmony_ci  bool is_shared_cross_origin =
3411cb0ef41Sopenharmony_ci      parsing_while_debugging == ParsingWhileDebugging::kYes;
3421cb0ef41Sopenharmony_ci  bool is_opaque = false;
3431cb0ef41Sopenharmony_ci  if (script.IsScript()) {
3441cb0ef41Sopenharmony_ci    auto script_origin_options = Script::cast(script).origin_options();
3451cb0ef41Sopenharmony_ci    if (script_origin_options.IsSharedCrossOrigin()) {
3461cb0ef41Sopenharmony_ci      is_shared_cross_origin = true;
3471cb0ef41Sopenharmony_ci    }
3481cb0ef41Sopenharmony_ci    if (script_origin_options.IsOpaque()) {
3491cb0ef41Sopenharmony_ci      is_opaque = true;
3501cb0ef41Sopenharmony_ci    }
3511cb0ef41Sopenharmony_ci  }
3521cb0ef41Sopenharmony_ci  return ScriptOriginOptions(is_shared_cross_origin, is_opaque);
3531cb0ef41Sopenharmony_ci}
3541cb0ef41Sopenharmony_ci
3551cb0ef41Sopenharmony_ci}  // namespace
3561cb0ef41Sopenharmony_ci
3571cb0ef41Sopenharmony_ci// ----------------------------------------------------------------------------
3581cb0ef41Sopenharmony_ci// Implementation of UnoptimizedCompilationJob
3591cb0ef41Sopenharmony_ci
3601cb0ef41Sopenharmony_ciCompilationJob::Status UnoptimizedCompilationJob::ExecuteJob() {
3611cb0ef41Sopenharmony_ci  // Delegate to the underlying implementation.
3621cb0ef41Sopenharmony_ci  DCHECK_EQ(state(), State::kReadyToExecute);
3631cb0ef41Sopenharmony_ci  ScopedTimer t(&time_taken_to_execute_);
3641cb0ef41Sopenharmony_ci  return UpdateState(ExecuteJobImpl(), State::kReadyToFinalize);
3651cb0ef41Sopenharmony_ci}
3661cb0ef41Sopenharmony_ci
3671cb0ef41Sopenharmony_ciCompilationJob::Status UnoptimizedCompilationJob::FinalizeJob(
3681cb0ef41Sopenharmony_ci    Handle<SharedFunctionInfo> shared_info, Isolate* isolate) {
3691cb0ef41Sopenharmony_ci  DCHECK_EQ(ThreadId::Current(), isolate->thread_id());
3701cb0ef41Sopenharmony_ci  DisallowCodeDependencyChange no_dependency_change;
3711cb0ef41Sopenharmony_ci  DisallowJavascriptExecution no_js(isolate);
3721cb0ef41Sopenharmony_ci
3731cb0ef41Sopenharmony_ci  // Delegate to the underlying implementation.
3741cb0ef41Sopenharmony_ci  DCHECK_EQ(state(), State::kReadyToFinalize);
3751cb0ef41Sopenharmony_ci  ScopedTimer t(&time_taken_to_finalize_);
3761cb0ef41Sopenharmony_ci  return UpdateState(FinalizeJobImpl(shared_info, isolate), State::kSucceeded);
3771cb0ef41Sopenharmony_ci}
3781cb0ef41Sopenharmony_ci
3791cb0ef41Sopenharmony_ciCompilationJob::Status UnoptimizedCompilationJob::FinalizeJob(
3801cb0ef41Sopenharmony_ci    Handle<SharedFunctionInfo> shared_info, LocalIsolate* isolate) {
3811cb0ef41Sopenharmony_ci  // Delegate to the underlying implementation.
3821cb0ef41Sopenharmony_ci  DCHECK_EQ(state(), State::kReadyToFinalize);
3831cb0ef41Sopenharmony_ci  ScopedTimer t(&time_taken_to_finalize_);
3841cb0ef41Sopenharmony_ci  return UpdateState(FinalizeJobImpl(shared_info, isolate), State::kSucceeded);
3851cb0ef41Sopenharmony_ci}
3861cb0ef41Sopenharmony_ci
3871cb0ef41Sopenharmony_cinamespace {
3881cb0ef41Sopenharmony_ci
3891cb0ef41Sopenharmony_civoid RecordUnoptimizedCompilationStats(Isolate* isolate,
3901cb0ef41Sopenharmony_ci                                       Handle<SharedFunctionInfo> shared_info) {
3911cb0ef41Sopenharmony_ci#if V8_ENABLE_WEBASSEMBLY
3921cb0ef41Sopenharmony_ci  int code_size =
3931cb0ef41Sopenharmony_ci      shared_info->HasBytecodeArray()
3941cb0ef41Sopenharmony_ci          ? shared_info->GetBytecodeArray(isolate).SizeIncludingMetadata()
3951cb0ef41Sopenharmony_ci          : shared_info->asm_wasm_data().Size();
3961cb0ef41Sopenharmony_ci#else
3971cb0ef41Sopenharmony_ci  int code_size =
3981cb0ef41Sopenharmony_ci      shared_info->GetBytecodeArray(isolate).SizeIncludingMetadata();
3991cb0ef41Sopenharmony_ci#endif  // V8_ENABLE_WEBASSEMBLY
4001cb0ef41Sopenharmony_ci
4011cb0ef41Sopenharmony_ci  Counters* counters = isolate->counters();
4021cb0ef41Sopenharmony_ci  // TODO(4280): Rename counters from "baseline" to "unoptimized" eventually.
4031cb0ef41Sopenharmony_ci  counters->total_baseline_code_size()->Increment(code_size);
4041cb0ef41Sopenharmony_ci  counters->total_baseline_compile_count()->Increment(1);
4051cb0ef41Sopenharmony_ci
4061cb0ef41Sopenharmony_ci  // TODO(5203): Add timers for each phase of compilation.
4071cb0ef41Sopenharmony_ci  // Also add total time (there's now already timer_ on the base class).
4081cb0ef41Sopenharmony_ci}
4091cb0ef41Sopenharmony_ci
4101cb0ef41Sopenharmony_civoid RecordUnoptimizedFunctionCompilation(
4111cb0ef41Sopenharmony_ci    Isolate* isolate, CodeEventListener::LogEventsAndTags tag,
4121cb0ef41Sopenharmony_ci    Handle<SharedFunctionInfo> shared, base::TimeDelta time_taken_to_execute,
4131cb0ef41Sopenharmony_ci    base::TimeDelta time_taken_to_finalize) {
4141cb0ef41Sopenharmony_ci  Handle<AbstractCode> abstract_code;
4151cb0ef41Sopenharmony_ci  if (shared->HasBytecodeArray()) {
4161cb0ef41Sopenharmony_ci    abstract_code =
4171cb0ef41Sopenharmony_ci        handle(AbstractCode::cast(shared->GetBytecodeArray(isolate)), isolate);
4181cb0ef41Sopenharmony_ci  } else {
4191cb0ef41Sopenharmony_ci#if V8_ENABLE_WEBASSEMBLY
4201cb0ef41Sopenharmony_ci    DCHECK(shared->HasAsmWasmData());
4211cb0ef41Sopenharmony_ci    abstract_code =
4221cb0ef41Sopenharmony_ci        ToAbstractCode(BUILTIN_CODE(isolate, InstantiateAsmJs), isolate);
4231cb0ef41Sopenharmony_ci#else
4241cb0ef41Sopenharmony_ci    UNREACHABLE();
4251cb0ef41Sopenharmony_ci#endif  // V8_ENABLE_WEBASSEMBLY
4261cb0ef41Sopenharmony_ci  }
4271cb0ef41Sopenharmony_ci
4281cb0ef41Sopenharmony_ci  double time_taken_ms = time_taken_to_execute.InMillisecondsF() +
4291cb0ef41Sopenharmony_ci                         time_taken_to_finalize.InMillisecondsF();
4301cb0ef41Sopenharmony_ci
4311cb0ef41Sopenharmony_ci  Handle<Script> script(Script::cast(shared->script()), isolate);
4321cb0ef41Sopenharmony_ci  LogFunctionCompilation(isolate, tag, script, shared, Handle<FeedbackVector>(),
4331cb0ef41Sopenharmony_ci                         abstract_code, CodeKind::INTERPRETED_FUNCTION,
4341cb0ef41Sopenharmony_ci                         time_taken_ms);
4351cb0ef41Sopenharmony_ci}
4361cb0ef41Sopenharmony_ci
4371cb0ef41Sopenharmony_ci}  // namespace
4381cb0ef41Sopenharmony_ci
4391cb0ef41Sopenharmony_ci// ----------------------------------------------------------------------------
4401cb0ef41Sopenharmony_ci// Implementation of OptimizedCompilationJob
4411cb0ef41Sopenharmony_ci
4421cb0ef41Sopenharmony_ciCompilationJob::Status OptimizedCompilationJob::PrepareJob(Isolate* isolate) {
4431cb0ef41Sopenharmony_ci  DCHECK_EQ(ThreadId::Current(), isolate->thread_id());
4441cb0ef41Sopenharmony_ci  DisallowJavascriptExecution no_js(isolate);
4451cb0ef41Sopenharmony_ci
4461cb0ef41Sopenharmony_ci  // Delegate to the underlying implementation.
4471cb0ef41Sopenharmony_ci  DCHECK_EQ(state(), State::kReadyToPrepare);
4481cb0ef41Sopenharmony_ci  ScopedTimer t(&time_taken_to_prepare_);
4491cb0ef41Sopenharmony_ci  return UpdateState(PrepareJobImpl(isolate), State::kReadyToExecute);
4501cb0ef41Sopenharmony_ci}
4511cb0ef41Sopenharmony_ci
4521cb0ef41Sopenharmony_ciCompilationJob::Status OptimizedCompilationJob::ExecuteJob(
4531cb0ef41Sopenharmony_ci    RuntimeCallStats* stats, LocalIsolate* local_isolate) {
4541cb0ef41Sopenharmony_ci  DCHECK_IMPLIES(local_isolate, local_isolate->heap()->IsParked());
4551cb0ef41Sopenharmony_ci  // Delegate to the underlying implementation.
4561cb0ef41Sopenharmony_ci  DCHECK_EQ(state(), State::kReadyToExecute);
4571cb0ef41Sopenharmony_ci  ScopedTimer t(&time_taken_to_execute_);
4581cb0ef41Sopenharmony_ci  return UpdateState(ExecuteJobImpl(stats, local_isolate),
4591cb0ef41Sopenharmony_ci                     State::kReadyToFinalize);
4601cb0ef41Sopenharmony_ci}
4611cb0ef41Sopenharmony_ci
4621cb0ef41Sopenharmony_ciCompilationJob::Status OptimizedCompilationJob::FinalizeJob(Isolate* isolate) {
4631cb0ef41Sopenharmony_ci  DCHECK_EQ(ThreadId::Current(), isolate->thread_id());
4641cb0ef41Sopenharmony_ci  DisallowJavascriptExecution no_js(isolate);
4651cb0ef41Sopenharmony_ci
4661cb0ef41Sopenharmony_ci  // Delegate to the underlying implementation.
4671cb0ef41Sopenharmony_ci  DCHECK_EQ(state(), State::kReadyToFinalize);
4681cb0ef41Sopenharmony_ci  ScopedTimer t(&time_taken_to_finalize_);
4691cb0ef41Sopenharmony_ci  return UpdateState(FinalizeJobImpl(isolate), State::kSucceeded);
4701cb0ef41Sopenharmony_ci}
4711cb0ef41Sopenharmony_ci
4721cb0ef41Sopenharmony_ciCompilationJob::Status TurbofanCompilationJob::RetryOptimization(
4731cb0ef41Sopenharmony_ci    BailoutReason reason) {
4741cb0ef41Sopenharmony_ci  DCHECK(compilation_info_->IsOptimizing());
4751cb0ef41Sopenharmony_ci  compilation_info_->RetryOptimization(reason);
4761cb0ef41Sopenharmony_ci  return UpdateState(FAILED, State::kFailed);
4771cb0ef41Sopenharmony_ci}
4781cb0ef41Sopenharmony_ci
4791cb0ef41Sopenharmony_ciCompilationJob::Status TurbofanCompilationJob::AbortOptimization(
4801cb0ef41Sopenharmony_ci    BailoutReason reason) {
4811cb0ef41Sopenharmony_ci  DCHECK(compilation_info_->IsOptimizing());
4821cb0ef41Sopenharmony_ci  compilation_info_->AbortOptimization(reason);
4831cb0ef41Sopenharmony_ci  return UpdateState(FAILED, State::kFailed);
4841cb0ef41Sopenharmony_ci}
4851cb0ef41Sopenharmony_ci
4861cb0ef41Sopenharmony_civoid TurbofanCompilationJob::RecordCompilationStats(ConcurrencyMode mode,
4871cb0ef41Sopenharmony_ci                                                    Isolate* isolate) const {
4881cb0ef41Sopenharmony_ci  DCHECK(compilation_info()->IsOptimizing());
4891cb0ef41Sopenharmony_ci  Handle<JSFunction> function = compilation_info()->closure();
4901cb0ef41Sopenharmony_ci  double ms_creategraph = time_taken_to_prepare_.InMillisecondsF();
4911cb0ef41Sopenharmony_ci  double ms_optimize = time_taken_to_execute_.InMillisecondsF();
4921cb0ef41Sopenharmony_ci  double ms_codegen = time_taken_to_finalize_.InMillisecondsF();
4931cb0ef41Sopenharmony_ci  CompilerTracer::TraceCompilationStats(
4941cb0ef41Sopenharmony_ci      isolate, compilation_info(), ms_creategraph, ms_optimize, ms_codegen);
4951cb0ef41Sopenharmony_ci  if (FLAG_trace_opt_stats) {
4961cb0ef41Sopenharmony_ci    static double compilation_time = 0.0;
4971cb0ef41Sopenharmony_ci    static int compiled_functions = 0;
4981cb0ef41Sopenharmony_ci    static int code_size = 0;
4991cb0ef41Sopenharmony_ci
5001cb0ef41Sopenharmony_ci    compilation_time += (ms_creategraph + ms_optimize + ms_codegen);
5011cb0ef41Sopenharmony_ci    compiled_functions++;
5021cb0ef41Sopenharmony_ci    code_size += function->shared().SourceSize();
5031cb0ef41Sopenharmony_ci    PrintF("Compiled: %d functions with %d byte source size in %fms.\n",
5041cb0ef41Sopenharmony_ci           compiled_functions, code_size, compilation_time);
5051cb0ef41Sopenharmony_ci  }
5061cb0ef41Sopenharmony_ci  // Don't record samples from machines without high-resolution timers,
5071cb0ef41Sopenharmony_ci  // as that can cause serious reporting issues. See the thread at
5081cb0ef41Sopenharmony_ci  // http://g/chrome-metrics-team/NwwJEyL8odU/discussion for more details.
5091cb0ef41Sopenharmony_ci  if (base::TimeTicks::IsHighResolution()) {
5101cb0ef41Sopenharmony_ci    Counters* const counters = isolate->counters();
5111cb0ef41Sopenharmony_ci    if (compilation_info()->is_osr()) {
5121cb0ef41Sopenharmony_ci      counters->turbofan_osr_prepare()->AddSample(
5131cb0ef41Sopenharmony_ci          static_cast<int>(time_taken_to_prepare_.InMicroseconds()));
5141cb0ef41Sopenharmony_ci      counters->turbofan_osr_execute()->AddSample(
5151cb0ef41Sopenharmony_ci          static_cast<int>(time_taken_to_execute_.InMicroseconds()));
5161cb0ef41Sopenharmony_ci      counters->turbofan_osr_finalize()->AddSample(
5171cb0ef41Sopenharmony_ci          static_cast<int>(time_taken_to_finalize_.InMicroseconds()));
5181cb0ef41Sopenharmony_ci      counters->turbofan_osr_total_time()->AddSample(
5191cb0ef41Sopenharmony_ci          static_cast<int>(ElapsedTime().InMicroseconds()));
5201cb0ef41Sopenharmony_ci    } else {
5211cb0ef41Sopenharmony_ci      counters->turbofan_optimize_prepare()->AddSample(
5221cb0ef41Sopenharmony_ci          static_cast<int>(time_taken_to_prepare_.InMicroseconds()));
5231cb0ef41Sopenharmony_ci      counters->turbofan_optimize_execute()->AddSample(
5241cb0ef41Sopenharmony_ci          static_cast<int>(time_taken_to_execute_.InMicroseconds()));
5251cb0ef41Sopenharmony_ci      counters->turbofan_optimize_finalize()->AddSample(
5261cb0ef41Sopenharmony_ci          static_cast<int>(time_taken_to_finalize_.InMicroseconds()));
5271cb0ef41Sopenharmony_ci      counters->turbofan_optimize_total_time()->AddSample(
5281cb0ef41Sopenharmony_ci          static_cast<int>(ElapsedTime().InMicroseconds()));
5291cb0ef41Sopenharmony_ci
5301cb0ef41Sopenharmony_ci      // Compute foreground / background time.
5311cb0ef41Sopenharmony_ci      base::TimeDelta time_background;
5321cb0ef41Sopenharmony_ci      base::TimeDelta time_foreground =
5331cb0ef41Sopenharmony_ci          time_taken_to_prepare_ + time_taken_to_finalize_;
5341cb0ef41Sopenharmony_ci      switch (mode) {
5351cb0ef41Sopenharmony_ci        case ConcurrencyMode::kConcurrent:
5361cb0ef41Sopenharmony_ci          time_background += time_taken_to_execute_;
5371cb0ef41Sopenharmony_ci          counters->turbofan_optimize_concurrent_total_time()->AddSample(
5381cb0ef41Sopenharmony_ci              static_cast<int>(ElapsedTime().InMicroseconds()));
5391cb0ef41Sopenharmony_ci          break;
5401cb0ef41Sopenharmony_ci        case ConcurrencyMode::kSynchronous:
5411cb0ef41Sopenharmony_ci          counters->turbofan_optimize_non_concurrent_total_time()->AddSample(
5421cb0ef41Sopenharmony_ci              static_cast<int>(ElapsedTime().InMicroseconds()));
5431cb0ef41Sopenharmony_ci          time_foreground += time_taken_to_execute_;
5441cb0ef41Sopenharmony_ci          break;
5451cb0ef41Sopenharmony_ci      }
5461cb0ef41Sopenharmony_ci      counters->turbofan_optimize_total_background()->AddSample(
5471cb0ef41Sopenharmony_ci          static_cast<int>(time_background.InMicroseconds()));
5481cb0ef41Sopenharmony_ci      counters->turbofan_optimize_total_foreground()->AddSample(
5491cb0ef41Sopenharmony_ci          static_cast<int>(time_foreground.InMicroseconds()));
5501cb0ef41Sopenharmony_ci    }
5511cb0ef41Sopenharmony_ci    counters->turbofan_ticks()->AddSample(static_cast<int>(
5521cb0ef41Sopenharmony_ci        compilation_info()->tick_counter().CurrentTicks() / 1000));
5531cb0ef41Sopenharmony_ci  }
5541cb0ef41Sopenharmony_ci}
5551cb0ef41Sopenharmony_ci
5561cb0ef41Sopenharmony_civoid TurbofanCompilationJob::RecordFunctionCompilation(
5571cb0ef41Sopenharmony_ci    CodeEventListener::LogEventsAndTags tag, Isolate* isolate) const {
5581cb0ef41Sopenharmony_ci  Handle<AbstractCode> abstract_code =
5591cb0ef41Sopenharmony_ci      Handle<AbstractCode>::cast(compilation_info()->code());
5601cb0ef41Sopenharmony_ci
5611cb0ef41Sopenharmony_ci  double time_taken_ms = time_taken_to_prepare_.InMillisecondsF() +
5621cb0ef41Sopenharmony_ci                         time_taken_to_execute_.InMillisecondsF() +
5631cb0ef41Sopenharmony_ci                         time_taken_to_finalize_.InMillisecondsF();
5641cb0ef41Sopenharmony_ci
5651cb0ef41Sopenharmony_ci  Handle<Script> script(
5661cb0ef41Sopenharmony_ci      Script::cast(compilation_info()->shared_info()->script()), isolate);
5671cb0ef41Sopenharmony_ci  Handle<FeedbackVector> feedback_vector(
5681cb0ef41Sopenharmony_ci      compilation_info()->closure()->feedback_vector(), isolate);
5691cb0ef41Sopenharmony_ci  LogFunctionCompilation(
5701cb0ef41Sopenharmony_ci      isolate, tag, script, compilation_info()->shared_info(), feedback_vector,
5711cb0ef41Sopenharmony_ci      abstract_code, compilation_info()->code_kind(), time_taken_ms);
5721cb0ef41Sopenharmony_ci}
5731cb0ef41Sopenharmony_ci
5741cb0ef41Sopenharmony_ci// ----------------------------------------------------------------------------
5751cb0ef41Sopenharmony_ci// Local helper methods that make up the compilation pipeline.
5761cb0ef41Sopenharmony_ci
5771cb0ef41Sopenharmony_cinamespace {
5781cb0ef41Sopenharmony_ci
5791cb0ef41Sopenharmony_ci#if V8_ENABLE_WEBASSEMBLY
5801cb0ef41Sopenharmony_cibool UseAsmWasm(FunctionLiteral* literal, bool asm_wasm_broken) {
5811cb0ef41Sopenharmony_ci  // Check whether asm.js validation is enabled.
5821cb0ef41Sopenharmony_ci  if (!FLAG_validate_asm) return false;
5831cb0ef41Sopenharmony_ci
5841cb0ef41Sopenharmony_ci  // Modules that have validated successfully, but were subsequently broken by
5851cb0ef41Sopenharmony_ci  // invalid module instantiation attempts are off limit forever.
5861cb0ef41Sopenharmony_ci  if (asm_wasm_broken) return false;
5871cb0ef41Sopenharmony_ci
5881cb0ef41Sopenharmony_ci  // In stress mode we want to run the validator on everything.
5891cb0ef41Sopenharmony_ci  if (FLAG_stress_validate_asm) return true;
5901cb0ef41Sopenharmony_ci
5911cb0ef41Sopenharmony_ci  // In general, we respect the "use asm" directive.
5921cb0ef41Sopenharmony_ci  return literal->scope()->IsAsmModule();
5931cb0ef41Sopenharmony_ci}
5941cb0ef41Sopenharmony_ci#endif
5951cb0ef41Sopenharmony_ci
5961cb0ef41Sopenharmony_civoid InstallInterpreterTrampolineCopy(
5971cb0ef41Sopenharmony_ci    Isolate* isolate, Handle<SharedFunctionInfo> shared_info,
5981cb0ef41Sopenharmony_ci    CodeEventListener::LogEventsAndTags log_tag) {
5991cb0ef41Sopenharmony_ci  DCHECK(FLAG_interpreted_frames_native_stack);
6001cb0ef41Sopenharmony_ci  if (!shared_info->function_data(kAcquireLoad).IsBytecodeArray()) {
6011cb0ef41Sopenharmony_ci    DCHECK(!shared_info->HasBytecodeArray());
6021cb0ef41Sopenharmony_ci    return;
6031cb0ef41Sopenharmony_ci  }
6041cb0ef41Sopenharmony_ci  Handle<BytecodeArray> bytecode_array(shared_info->GetBytecodeArray(isolate),
6051cb0ef41Sopenharmony_ci                                       isolate);
6061cb0ef41Sopenharmony_ci
6071cb0ef41Sopenharmony_ci  Handle<Code> code = isolate->factory()->CopyCode(Handle<Code>::cast(
6081cb0ef41Sopenharmony_ci      isolate->factory()->interpreter_entry_trampoline_for_profiling()));
6091cb0ef41Sopenharmony_ci
6101cb0ef41Sopenharmony_ci  Handle<InterpreterData> interpreter_data =
6111cb0ef41Sopenharmony_ci      Handle<InterpreterData>::cast(isolate->factory()->NewStruct(
6121cb0ef41Sopenharmony_ci          INTERPRETER_DATA_TYPE, AllocationType::kOld));
6131cb0ef41Sopenharmony_ci
6141cb0ef41Sopenharmony_ci  interpreter_data->set_bytecode_array(*bytecode_array);
6151cb0ef41Sopenharmony_ci  interpreter_data->set_interpreter_trampoline(ToCodeT(*code));
6161cb0ef41Sopenharmony_ci
6171cb0ef41Sopenharmony_ci  shared_info->set_interpreter_data(*interpreter_data);
6181cb0ef41Sopenharmony_ci
6191cb0ef41Sopenharmony_ci  Handle<Script> script(Script::cast(shared_info->script()), isolate);
6201cb0ef41Sopenharmony_ci  Handle<AbstractCode> abstract_code = Handle<AbstractCode>::cast(code);
6211cb0ef41Sopenharmony_ci  int line_num =
6221cb0ef41Sopenharmony_ci      Script::GetLineNumber(script, shared_info->StartPosition()) + 1;
6231cb0ef41Sopenharmony_ci  int column_num =
6241cb0ef41Sopenharmony_ci      Script::GetColumnNumber(script, shared_info->StartPosition()) + 1;
6251cb0ef41Sopenharmony_ci  Handle<String> script_name =
6261cb0ef41Sopenharmony_ci      handle(script->name().IsString() ? String::cast(script->name())
6271cb0ef41Sopenharmony_ci                                       : ReadOnlyRoots(isolate).empty_string(),
6281cb0ef41Sopenharmony_ci             isolate);
6291cb0ef41Sopenharmony_ci  PROFILE(isolate, CodeCreateEvent(log_tag, abstract_code, shared_info,
6301cb0ef41Sopenharmony_ci                                   script_name, line_num, column_num));
6311cb0ef41Sopenharmony_ci}
6321cb0ef41Sopenharmony_ci
6331cb0ef41Sopenharmony_citemplate <typename IsolateT>
6341cb0ef41Sopenharmony_civoid InstallUnoptimizedCode(UnoptimizedCompilationInfo* compilation_info,
6351cb0ef41Sopenharmony_ci                            Handle<SharedFunctionInfo> shared_info,
6361cb0ef41Sopenharmony_ci                            IsolateT* isolate) {
6371cb0ef41Sopenharmony_ci  if (compilation_info->has_bytecode_array()) {
6381cb0ef41Sopenharmony_ci    DCHECK(!shared_info->HasBytecodeArray());  // Only compiled once.
6391cb0ef41Sopenharmony_ci    DCHECK(!compilation_info->has_asm_wasm_data());
6401cb0ef41Sopenharmony_ci    DCHECK(!shared_info->HasFeedbackMetadata());
6411cb0ef41Sopenharmony_ci
6421cb0ef41Sopenharmony_ci#if V8_ENABLE_WEBASSEMBLY
6431cb0ef41Sopenharmony_ci    // If the function failed asm-wasm compilation, mark asm_wasm as broken
6441cb0ef41Sopenharmony_ci    // to ensure we don't try to compile as asm-wasm.
6451cb0ef41Sopenharmony_ci    if (compilation_info->literal()->scope()->IsAsmModule()) {
6461cb0ef41Sopenharmony_ci      shared_info->set_is_asm_wasm_broken(true);
6471cb0ef41Sopenharmony_ci    }
6481cb0ef41Sopenharmony_ci#endif  // V8_ENABLE_WEBASSEMBLY
6491cb0ef41Sopenharmony_ci
6501cb0ef41Sopenharmony_ci    shared_info->set_bytecode_array(*compilation_info->bytecode_array());
6511cb0ef41Sopenharmony_ci
6521cb0ef41Sopenharmony_ci    Handle<FeedbackMetadata> feedback_metadata = FeedbackMetadata::New(
6531cb0ef41Sopenharmony_ci        isolate, compilation_info->feedback_vector_spec());
6541cb0ef41Sopenharmony_ci    shared_info->set_feedback_metadata(*feedback_metadata, kReleaseStore);
6551cb0ef41Sopenharmony_ci  } else {
6561cb0ef41Sopenharmony_ci#if V8_ENABLE_WEBASSEMBLY
6571cb0ef41Sopenharmony_ci    DCHECK(compilation_info->has_asm_wasm_data());
6581cb0ef41Sopenharmony_ci    // We should only have asm/wasm data when finalizing on the main thread.
6591cb0ef41Sopenharmony_ci    DCHECK((std::is_same<IsolateT, Isolate>::value));
6601cb0ef41Sopenharmony_ci    shared_info->set_asm_wasm_data(*compilation_info->asm_wasm_data());
6611cb0ef41Sopenharmony_ci    shared_info->set_feedback_metadata(
6621cb0ef41Sopenharmony_ci        ReadOnlyRoots(isolate).empty_feedback_metadata(), kReleaseStore);
6631cb0ef41Sopenharmony_ci#else
6641cb0ef41Sopenharmony_ci    UNREACHABLE();
6651cb0ef41Sopenharmony_ci#endif  // V8_ENABLE_WEBASSEMBLY
6661cb0ef41Sopenharmony_ci  }
6671cb0ef41Sopenharmony_ci}
6681cb0ef41Sopenharmony_ci
6691cb0ef41Sopenharmony_civoid LogUnoptimizedCompilation(Isolate* isolate,
6701cb0ef41Sopenharmony_ci                               Handle<SharedFunctionInfo> shared_info,
6711cb0ef41Sopenharmony_ci                               CodeEventListener::LogEventsAndTags log_tag,
6721cb0ef41Sopenharmony_ci                               base::TimeDelta time_taken_to_execute,
6731cb0ef41Sopenharmony_ci                               base::TimeDelta time_taken_to_finalize) {
6741cb0ef41Sopenharmony_ci  RecordUnoptimizedFunctionCompilation(isolate, log_tag, shared_info,
6751cb0ef41Sopenharmony_ci                                       time_taken_to_execute,
6761cb0ef41Sopenharmony_ci                                       time_taken_to_finalize);
6771cb0ef41Sopenharmony_ci  RecordUnoptimizedCompilationStats(isolate, shared_info);
6781cb0ef41Sopenharmony_ci}
6791cb0ef41Sopenharmony_ci
6801cb0ef41Sopenharmony_citemplate <typename IsolateT>
6811cb0ef41Sopenharmony_civoid EnsureSharedFunctionInfosArrayOnScript(Handle<Script> script,
6821cb0ef41Sopenharmony_ci                                            ParseInfo* parse_info,
6831cb0ef41Sopenharmony_ci                                            IsolateT* isolate) {
6841cb0ef41Sopenharmony_ci  DCHECK(parse_info->flags().is_toplevel());
6851cb0ef41Sopenharmony_ci  if (script->shared_function_info_count() > 0) {
6861cb0ef41Sopenharmony_ci    DCHECK_LE(script->shared_function_info_count(),
6871cb0ef41Sopenharmony_ci              script->shared_function_infos().length());
6881cb0ef41Sopenharmony_ci    DCHECK_EQ(script->shared_function_info_count(),
6891cb0ef41Sopenharmony_ci              parse_info->max_function_literal_id() + 1);
6901cb0ef41Sopenharmony_ci    return;
6911cb0ef41Sopenharmony_ci  }
6921cb0ef41Sopenharmony_ci  Handle<WeakFixedArray> infos(isolate->factory()->NewWeakFixedArray(
6931cb0ef41Sopenharmony_ci      parse_info->max_function_literal_id() + 1, AllocationType::kOld));
6941cb0ef41Sopenharmony_ci  script->set_shared_function_infos(*infos);
6951cb0ef41Sopenharmony_ci}
6961cb0ef41Sopenharmony_ci
6971cb0ef41Sopenharmony_civoid UpdateSharedFunctionFlagsAfterCompilation(FunctionLiteral* literal,
6981cb0ef41Sopenharmony_ci                                               SharedFunctionInfo shared_info) {
6991cb0ef41Sopenharmony_ci  DCHECK_EQ(shared_info.language_mode(), literal->language_mode());
7001cb0ef41Sopenharmony_ci
7011cb0ef41Sopenharmony_ci  // These fields are all initialised in ParseInfo from the SharedFunctionInfo,
7021cb0ef41Sopenharmony_ci  // and then set back on the literal after parse. Hence, they should already
7031cb0ef41Sopenharmony_ci  // match.
7041cb0ef41Sopenharmony_ci  DCHECK_EQ(shared_info.requires_instance_members_initializer(),
7051cb0ef41Sopenharmony_ci            literal->requires_instance_members_initializer());
7061cb0ef41Sopenharmony_ci  DCHECK_EQ(shared_info.class_scope_has_private_brand(),
7071cb0ef41Sopenharmony_ci            literal->class_scope_has_private_brand());
7081cb0ef41Sopenharmony_ci  DCHECK_EQ(shared_info.has_static_private_methods_or_accessors(),
7091cb0ef41Sopenharmony_ci            literal->has_static_private_methods_or_accessors());
7101cb0ef41Sopenharmony_ci
7111cb0ef41Sopenharmony_ci  shared_info.set_has_duplicate_parameters(literal->has_duplicate_parameters());
7121cb0ef41Sopenharmony_ci  shared_info.UpdateAndFinalizeExpectedNofPropertiesFromEstimate(literal);
7131cb0ef41Sopenharmony_ci
7141cb0ef41Sopenharmony_ci  shared_info.SetScopeInfo(*literal->scope()->scope_info());
7151cb0ef41Sopenharmony_ci}
7161cb0ef41Sopenharmony_ci
7171cb0ef41Sopenharmony_ci// Finalize a single compilation job. This function can return
7181cb0ef41Sopenharmony_ci// RETRY_ON_MAIN_THREAD if the job cannot be finalized off-thread, in which case
7191cb0ef41Sopenharmony_ci// it should be safe to call it again on the main thread with the same job.
7201cb0ef41Sopenharmony_citemplate <typename IsolateT>
7211cb0ef41Sopenharmony_ciCompilationJob::Status FinalizeSingleUnoptimizedCompilationJob(
7221cb0ef41Sopenharmony_ci    UnoptimizedCompilationJob* job, Handle<SharedFunctionInfo> shared_info,
7231cb0ef41Sopenharmony_ci    IsolateT* isolate,
7241cb0ef41Sopenharmony_ci    FinalizeUnoptimizedCompilationDataList*
7251cb0ef41Sopenharmony_ci        finalize_unoptimized_compilation_data_list) {
7261cb0ef41Sopenharmony_ci  UnoptimizedCompilationInfo* compilation_info = job->compilation_info();
7271cb0ef41Sopenharmony_ci
7281cb0ef41Sopenharmony_ci  CompilationJob::Status status = job->FinalizeJob(shared_info, isolate);
7291cb0ef41Sopenharmony_ci  if (status == CompilationJob::SUCCEEDED) {
7301cb0ef41Sopenharmony_ci    InstallUnoptimizedCode(compilation_info, shared_info, isolate);
7311cb0ef41Sopenharmony_ci
7321cb0ef41Sopenharmony_ci    MaybeHandle<CoverageInfo> coverage_info;
7331cb0ef41Sopenharmony_ci    if (compilation_info->has_coverage_info() &&
7341cb0ef41Sopenharmony_ci        !shared_info->HasCoverageInfo()) {
7351cb0ef41Sopenharmony_ci      coverage_info = compilation_info->coverage_info();
7361cb0ef41Sopenharmony_ci    }
7371cb0ef41Sopenharmony_ci
7381cb0ef41Sopenharmony_ci    finalize_unoptimized_compilation_data_list->emplace_back(
7391cb0ef41Sopenharmony_ci        isolate, shared_info, coverage_info, job->time_taken_to_execute(),
7401cb0ef41Sopenharmony_ci        job->time_taken_to_finalize());
7411cb0ef41Sopenharmony_ci  }
7421cb0ef41Sopenharmony_ci  DCHECK_IMPLIES(status == CompilationJob::RETRY_ON_MAIN_THREAD,
7431cb0ef41Sopenharmony_ci                 (std::is_same<IsolateT, LocalIsolate>::value));
7441cb0ef41Sopenharmony_ci  return status;
7451cb0ef41Sopenharmony_ci}
7461cb0ef41Sopenharmony_ci
7471cb0ef41Sopenharmony_cistd::unique_ptr<UnoptimizedCompilationJob>
7481cb0ef41Sopenharmony_ciExecuteSingleUnoptimizedCompilationJob(
7491cb0ef41Sopenharmony_ci    ParseInfo* parse_info, FunctionLiteral* literal, Handle<Script> script,
7501cb0ef41Sopenharmony_ci    AccountingAllocator* allocator,
7511cb0ef41Sopenharmony_ci    std::vector<FunctionLiteral*>* eager_inner_literals,
7521cb0ef41Sopenharmony_ci    LocalIsolate* local_isolate) {
7531cb0ef41Sopenharmony_ci#if V8_ENABLE_WEBASSEMBLY
7541cb0ef41Sopenharmony_ci  if (UseAsmWasm(literal, parse_info->flags().is_asm_wasm_broken())) {
7551cb0ef41Sopenharmony_ci    std::unique_ptr<UnoptimizedCompilationJob> asm_job(
7561cb0ef41Sopenharmony_ci        AsmJs::NewCompilationJob(parse_info, literal, allocator));
7571cb0ef41Sopenharmony_ci    if (asm_job->ExecuteJob() == CompilationJob::SUCCEEDED) {
7581cb0ef41Sopenharmony_ci      return asm_job;
7591cb0ef41Sopenharmony_ci    }
7601cb0ef41Sopenharmony_ci    // asm.js validation failed, fall through to standard unoptimized compile.
7611cb0ef41Sopenharmony_ci    // Note: we rely on the fact that AsmJs jobs have done all validation in the
7621cb0ef41Sopenharmony_ci    // PrepareJob and ExecuteJob phases and can't fail in FinalizeJob with
7631cb0ef41Sopenharmony_ci    // with a validation error or another error that could be solve by falling
7641cb0ef41Sopenharmony_ci    // through to standard unoptimized compile.
7651cb0ef41Sopenharmony_ci  }
7661cb0ef41Sopenharmony_ci#endif
7671cb0ef41Sopenharmony_ci  std::unique_ptr<UnoptimizedCompilationJob> job(
7681cb0ef41Sopenharmony_ci      interpreter::Interpreter::NewCompilationJob(
7691cb0ef41Sopenharmony_ci          parse_info, literal, script, allocator, eager_inner_literals,
7701cb0ef41Sopenharmony_ci          local_isolate));
7711cb0ef41Sopenharmony_ci
7721cb0ef41Sopenharmony_ci  if (job->ExecuteJob() != CompilationJob::SUCCEEDED) {
7731cb0ef41Sopenharmony_ci    // Compilation failed, return null.
7741cb0ef41Sopenharmony_ci    return std::unique_ptr<UnoptimizedCompilationJob>();
7751cb0ef41Sopenharmony_ci  }
7761cb0ef41Sopenharmony_ci
7771cb0ef41Sopenharmony_ci  return job;
7781cb0ef41Sopenharmony_ci}
7791cb0ef41Sopenharmony_ci
7801cb0ef41Sopenharmony_citemplate <typename IsolateT>
7811cb0ef41Sopenharmony_cibool IterativelyExecuteAndFinalizeUnoptimizedCompilationJobs(
7821cb0ef41Sopenharmony_ci    IsolateT* isolate, Handle<SharedFunctionInfo> outer_shared_info,
7831cb0ef41Sopenharmony_ci    Handle<Script> script, ParseInfo* parse_info,
7841cb0ef41Sopenharmony_ci    AccountingAllocator* allocator, IsCompiledScope* is_compiled_scope,
7851cb0ef41Sopenharmony_ci    FinalizeUnoptimizedCompilationDataList*
7861cb0ef41Sopenharmony_ci        finalize_unoptimized_compilation_data_list,
7871cb0ef41Sopenharmony_ci    DeferredFinalizationJobDataList*
7881cb0ef41Sopenharmony_ci        jobs_to_retry_finalization_on_main_thread) {
7891cb0ef41Sopenharmony_ci  DeclarationScope::AllocateScopeInfos(parse_info, isolate);
7901cb0ef41Sopenharmony_ci
7911cb0ef41Sopenharmony_ci  std::vector<FunctionLiteral*> functions_to_compile;
7921cb0ef41Sopenharmony_ci  functions_to_compile.push_back(parse_info->literal());
7931cb0ef41Sopenharmony_ci
7941cb0ef41Sopenharmony_ci  bool is_first = true;
7951cb0ef41Sopenharmony_ci  while (!functions_to_compile.empty()) {
7961cb0ef41Sopenharmony_ci    FunctionLiteral* literal = functions_to_compile.back();
7971cb0ef41Sopenharmony_ci    functions_to_compile.pop_back();
7981cb0ef41Sopenharmony_ci    Handle<SharedFunctionInfo> shared_info;
7991cb0ef41Sopenharmony_ci    if (is_first) {
8001cb0ef41Sopenharmony_ci      // We get the first SharedFunctionInfo directly as outer_shared_info
8011cb0ef41Sopenharmony_ci      // rather than with Compiler::GetSharedFunctionInfo, to support
8021cb0ef41Sopenharmony_ci      // placeholder SharedFunctionInfos that aren't on the script's SFI list.
8031cb0ef41Sopenharmony_ci      DCHECK_EQ(literal->function_literal_id(),
8041cb0ef41Sopenharmony_ci                outer_shared_info->function_literal_id());
8051cb0ef41Sopenharmony_ci      shared_info = outer_shared_info;
8061cb0ef41Sopenharmony_ci      is_first = false;
8071cb0ef41Sopenharmony_ci    } else {
8081cb0ef41Sopenharmony_ci      shared_info = Compiler::GetSharedFunctionInfo(literal, script, isolate);
8091cb0ef41Sopenharmony_ci    }
8101cb0ef41Sopenharmony_ci
8111cb0ef41Sopenharmony_ci    if (shared_info->is_compiled()) continue;
8121cb0ef41Sopenharmony_ci
8131cb0ef41Sopenharmony_ci    std::unique_ptr<UnoptimizedCompilationJob> job =
8141cb0ef41Sopenharmony_ci        ExecuteSingleUnoptimizedCompilationJob(parse_info, literal, script,
8151cb0ef41Sopenharmony_ci                                               allocator, &functions_to_compile,
8161cb0ef41Sopenharmony_ci                                               isolate->AsLocalIsolate());
8171cb0ef41Sopenharmony_ci
8181cb0ef41Sopenharmony_ci    if (!job) return false;
8191cb0ef41Sopenharmony_ci
8201cb0ef41Sopenharmony_ci    UpdateSharedFunctionFlagsAfterCompilation(literal, *shared_info);
8211cb0ef41Sopenharmony_ci
8221cb0ef41Sopenharmony_ci    auto finalization_status = FinalizeSingleUnoptimizedCompilationJob(
8231cb0ef41Sopenharmony_ci        job.get(), shared_info, isolate,
8241cb0ef41Sopenharmony_ci        finalize_unoptimized_compilation_data_list);
8251cb0ef41Sopenharmony_ci
8261cb0ef41Sopenharmony_ci    switch (finalization_status) {
8271cb0ef41Sopenharmony_ci      case CompilationJob::SUCCEEDED:
8281cb0ef41Sopenharmony_ci        if (shared_info.is_identical_to(outer_shared_info)) {
8291cb0ef41Sopenharmony_ci          // Ensure that the top level function is retained.
8301cb0ef41Sopenharmony_ci          *is_compiled_scope = shared_info->is_compiled_scope(isolate);
8311cb0ef41Sopenharmony_ci          DCHECK(is_compiled_scope->is_compiled());
8321cb0ef41Sopenharmony_ci        }
8331cb0ef41Sopenharmony_ci        break;
8341cb0ef41Sopenharmony_ci
8351cb0ef41Sopenharmony_ci      case CompilationJob::FAILED:
8361cb0ef41Sopenharmony_ci        return false;
8371cb0ef41Sopenharmony_ci
8381cb0ef41Sopenharmony_ci      case CompilationJob::RETRY_ON_MAIN_THREAD:
8391cb0ef41Sopenharmony_ci        // This should not happen on the main thread.
8401cb0ef41Sopenharmony_ci        DCHECK((!std::is_same<IsolateT, Isolate>::value));
8411cb0ef41Sopenharmony_ci        DCHECK_NOT_NULL(jobs_to_retry_finalization_on_main_thread);
8421cb0ef41Sopenharmony_ci
8431cb0ef41Sopenharmony_ci        // Clear the literal and ParseInfo to prevent further attempts to
8441cb0ef41Sopenharmony_ci        // access them.
8451cb0ef41Sopenharmony_ci        job->compilation_info()->ClearLiteral();
8461cb0ef41Sopenharmony_ci        job->ClearParseInfo();
8471cb0ef41Sopenharmony_ci        jobs_to_retry_finalization_on_main_thread->emplace_back(
8481cb0ef41Sopenharmony_ci            isolate, shared_info, std::move(job));
8491cb0ef41Sopenharmony_ci        break;
8501cb0ef41Sopenharmony_ci    }
8511cb0ef41Sopenharmony_ci  }
8521cb0ef41Sopenharmony_ci
8531cb0ef41Sopenharmony_ci  // Report any warnings generated during compilation.
8541cb0ef41Sopenharmony_ci  if (parse_info->pending_error_handler()->has_pending_warnings()) {
8551cb0ef41Sopenharmony_ci    parse_info->pending_error_handler()->PrepareWarnings(isolate);
8561cb0ef41Sopenharmony_ci  }
8571cb0ef41Sopenharmony_ci
8581cb0ef41Sopenharmony_ci  return true;
8591cb0ef41Sopenharmony_ci}
8601cb0ef41Sopenharmony_ci
8611cb0ef41Sopenharmony_cibool FinalizeDeferredUnoptimizedCompilationJobs(
8621cb0ef41Sopenharmony_ci    Isolate* isolate, Handle<Script> script,
8631cb0ef41Sopenharmony_ci    DeferredFinalizationJobDataList* deferred_jobs,
8641cb0ef41Sopenharmony_ci    PendingCompilationErrorHandler* pending_error_handler,
8651cb0ef41Sopenharmony_ci    FinalizeUnoptimizedCompilationDataList*
8661cb0ef41Sopenharmony_ci        finalize_unoptimized_compilation_data_list) {
8671cb0ef41Sopenharmony_ci  DCHECK(AllowCompilation::IsAllowed(isolate));
8681cb0ef41Sopenharmony_ci
8691cb0ef41Sopenharmony_ci  if (deferred_jobs->empty()) return true;
8701cb0ef41Sopenharmony_ci
8711cb0ef41Sopenharmony_ci  // TODO(rmcilroy): Clear native context in debug once AsmJS generates doesn't
8721cb0ef41Sopenharmony_ci  // rely on accessing native context during finalization.
8731cb0ef41Sopenharmony_ci
8741cb0ef41Sopenharmony_ci  // Finalize the deferred compilation jobs.
8751cb0ef41Sopenharmony_ci  for (auto&& job : *deferred_jobs) {
8761cb0ef41Sopenharmony_ci    Handle<SharedFunctionInfo> shared_info = job.function_handle();
8771cb0ef41Sopenharmony_ci    if (FinalizeSingleUnoptimizedCompilationJob(
8781cb0ef41Sopenharmony_ci            job.job(), shared_info, isolate,
8791cb0ef41Sopenharmony_ci            finalize_unoptimized_compilation_data_list) !=
8801cb0ef41Sopenharmony_ci        CompilationJob::SUCCEEDED) {
8811cb0ef41Sopenharmony_ci      return false;
8821cb0ef41Sopenharmony_ci    }
8831cb0ef41Sopenharmony_ci  }
8841cb0ef41Sopenharmony_ci
8851cb0ef41Sopenharmony_ci  // Report any warnings generated during deferred finalization.
8861cb0ef41Sopenharmony_ci  if (pending_error_handler->has_pending_warnings()) {
8871cb0ef41Sopenharmony_ci    pending_error_handler->PrepareWarnings(isolate);
8881cb0ef41Sopenharmony_ci  }
8891cb0ef41Sopenharmony_ci
8901cb0ef41Sopenharmony_ci  return true;
8911cb0ef41Sopenharmony_ci}
8921cb0ef41Sopenharmony_ci
8931cb0ef41Sopenharmony_ci// A wrapper to access either the OSR optimized code cache (one per native
8941cb0ef41Sopenharmony_ci// context), or the optimized code cache slot on the feedback vector.
8951cb0ef41Sopenharmony_ciclass OptimizedCodeCache : public AllStatic {
8961cb0ef41Sopenharmony_ci public:
8971cb0ef41Sopenharmony_ci  static V8_WARN_UNUSED_RESULT MaybeHandle<CodeT> Get(
8981cb0ef41Sopenharmony_ci      Isolate* isolate, Handle<JSFunction> function, BytecodeOffset osr_offset,
8991cb0ef41Sopenharmony_ci      CodeKind code_kind) {
9001cb0ef41Sopenharmony_ci    if (!CodeKindIsStoredInOptimizedCodeCache(code_kind)) return {};
9011cb0ef41Sopenharmony_ci
9021cb0ef41Sopenharmony_ci    DisallowGarbageCollection no_gc;
9031cb0ef41Sopenharmony_ci    SharedFunctionInfo shared = function->shared();
9041cb0ef41Sopenharmony_ci    RCS_SCOPE(isolate, RuntimeCallCounterId::kCompileGetFromOptimizedCodeMap);
9051cb0ef41Sopenharmony_ci
9061cb0ef41Sopenharmony_ci    CodeT code;
9071cb0ef41Sopenharmony_ci    if (IsOSR(osr_offset)) {
9081cb0ef41Sopenharmony_ci      // For OSR, check the OSR optimized code cache.
9091cb0ef41Sopenharmony_ci      code = function->native_context().osr_code_cache().TryGet(
9101cb0ef41Sopenharmony_ci          shared, osr_offset, isolate);
9111cb0ef41Sopenharmony_ci    } else {
9121cb0ef41Sopenharmony_ci      // Non-OSR code may be cached on the feedback vector.
9131cb0ef41Sopenharmony_ci      if (function->has_feedback_vector()) {
9141cb0ef41Sopenharmony_ci        FeedbackVector feedback_vector = function->feedback_vector();
9151cb0ef41Sopenharmony_ci        feedback_vector.EvictOptimizedCodeMarkedForDeoptimization(
9161cb0ef41Sopenharmony_ci            shared, "OptimizedCodeCache::Get");
9171cb0ef41Sopenharmony_ci        code = feedback_vector.optimized_code();
9181cb0ef41Sopenharmony_ci      }
9191cb0ef41Sopenharmony_ci    }
9201cb0ef41Sopenharmony_ci
9211cb0ef41Sopenharmony_ci    DCHECK_IMPLIES(!code.is_null(), code.kind() <= code_kind);
9221cb0ef41Sopenharmony_ci    if (code.is_null() || code.kind() != code_kind) return {};
9231cb0ef41Sopenharmony_ci
9241cb0ef41Sopenharmony_ci    DCHECK(!code.marked_for_deoptimization());
9251cb0ef41Sopenharmony_ci    DCHECK(shared.is_compiled());
9261cb0ef41Sopenharmony_ci    DCHECK(CodeKindIsStoredInOptimizedCodeCache(code.kind()));
9271cb0ef41Sopenharmony_ci    DCHECK_IMPLIES(IsOSR(osr_offset), CodeKindCanOSR(code.kind()));
9281cb0ef41Sopenharmony_ci
9291cb0ef41Sopenharmony_ci    CompilerTracer::TraceOptimizedCodeCacheHit(isolate, function, osr_offset,
9301cb0ef41Sopenharmony_ci                                               code_kind);
9311cb0ef41Sopenharmony_ci    return handle(code, isolate);
9321cb0ef41Sopenharmony_ci  }
9331cb0ef41Sopenharmony_ci
9341cb0ef41Sopenharmony_ci  static void Insert(OptimizedCompilationInfo* compilation_info) {
9351cb0ef41Sopenharmony_ci    const CodeKind kind = compilation_info->code_kind();
9361cb0ef41Sopenharmony_ci    if (!CodeKindIsStoredInOptimizedCodeCache(kind)) return;
9371cb0ef41Sopenharmony_ci
9381cb0ef41Sopenharmony_ci    // Cache optimized code.
9391cb0ef41Sopenharmony_ci    Handle<JSFunction> function = compilation_info->closure();
9401cb0ef41Sopenharmony_ci    Isolate* isolate = function->GetIsolate();
9411cb0ef41Sopenharmony_ci    Handle<CodeT> code = ToCodeT(compilation_info->code(), isolate);
9421cb0ef41Sopenharmony_ci    const BytecodeOffset osr_offset = compilation_info->osr_offset();
9431cb0ef41Sopenharmony_ci
9441cb0ef41Sopenharmony_ci    if (IsOSR(osr_offset)) {
9451cb0ef41Sopenharmony_ci      DCHECK(CodeKindCanOSR(kind));
9461cb0ef41Sopenharmony_ci      DCHECK(!compilation_info->function_context_specializing());
9471cb0ef41Sopenharmony_ci      Handle<SharedFunctionInfo> shared(function->shared(), isolate);
9481cb0ef41Sopenharmony_ci      Handle<NativeContext> native_context(function->native_context(), isolate);
9491cb0ef41Sopenharmony_ci      OSROptimizedCodeCache::Insert(isolate, native_context, shared, code,
9501cb0ef41Sopenharmony_ci                                    osr_offset);
9511cb0ef41Sopenharmony_ci      return;
9521cb0ef41Sopenharmony_ci    }
9531cb0ef41Sopenharmony_ci
9541cb0ef41Sopenharmony_ci    DCHECK(!IsOSR(osr_offset));
9551cb0ef41Sopenharmony_ci
9561cb0ef41Sopenharmony_ci    if (compilation_info->function_context_specializing()) {
9571cb0ef41Sopenharmony_ci      // Function context specialization folds-in the function context, so no
9581cb0ef41Sopenharmony_ci      // sharing can occur. Make sure the optimized code cache is cleared.
9591cb0ef41Sopenharmony_ci      if (function->feedback_vector().has_optimized_code()) {
9601cb0ef41Sopenharmony_ci        function->feedback_vector().ClearOptimizedCode();
9611cb0ef41Sopenharmony_ci      }
9621cb0ef41Sopenharmony_ci      return;
9631cb0ef41Sopenharmony_ci    }
9641cb0ef41Sopenharmony_ci
9651cb0ef41Sopenharmony_ci    function->feedback_vector().SetOptimizedCode(code);
9661cb0ef41Sopenharmony_ci  }
9671cb0ef41Sopenharmony_ci};
9681cb0ef41Sopenharmony_ci
9691cb0ef41Sopenharmony_ci// Runs PrepareJob in the proper compilation & canonical scopes. Handles will be
9701cb0ef41Sopenharmony_ci// allocated in a persistent handle scope that is detached and handed off to the
9711cb0ef41Sopenharmony_ci// {compilation_info} after PrepareJob.
9721cb0ef41Sopenharmony_cibool PrepareJobWithHandleScope(OptimizedCompilationJob* job, Isolate* isolate,
9731cb0ef41Sopenharmony_ci                               OptimizedCompilationInfo* compilation_info) {
9741cb0ef41Sopenharmony_ci  CompilationHandleScope compilation(isolate, compilation_info);
9751cb0ef41Sopenharmony_ci  CanonicalHandleScopeForTurbofan canonical(isolate, compilation_info);
9761cb0ef41Sopenharmony_ci  CompilerTracer::TracePrepareJob(isolate, compilation_info,
9771cb0ef41Sopenharmony_ci                                  job->compiler_name());
9781cb0ef41Sopenharmony_ci  compilation_info->ReopenHandlesInNewHandleScope(isolate);
9791cb0ef41Sopenharmony_ci  return job->PrepareJob(isolate) == CompilationJob::SUCCEEDED;
9801cb0ef41Sopenharmony_ci}
9811cb0ef41Sopenharmony_ci
9821cb0ef41Sopenharmony_cibool CompileTurbofan_NotConcurrent(Isolate* isolate,
9831cb0ef41Sopenharmony_ci                                   TurbofanCompilationJob* job) {
9841cb0ef41Sopenharmony_ci  OptimizedCompilationInfo* const compilation_info = job->compilation_info();
9851cb0ef41Sopenharmony_ci  DCHECK_EQ(compilation_info->code_kind(), CodeKind::TURBOFAN);
9861cb0ef41Sopenharmony_ci
9871cb0ef41Sopenharmony_ci  TimerEventScope<TimerEventRecompileSynchronous> timer(isolate);
9881cb0ef41Sopenharmony_ci  RCS_SCOPE(isolate, RuntimeCallCounterId::kOptimizeNonConcurrent);
9891cb0ef41Sopenharmony_ci  TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.compile"),
9901cb0ef41Sopenharmony_ci               "V8.OptimizeNonConcurrent");
9911cb0ef41Sopenharmony_ci
9921cb0ef41Sopenharmony_ci  if (!PrepareJobWithHandleScope(job, isolate, compilation_info)) {
9931cb0ef41Sopenharmony_ci    CompilerTracer::TraceAbortedJob(isolate, compilation_info);
9941cb0ef41Sopenharmony_ci    return false;
9951cb0ef41Sopenharmony_ci  }
9961cb0ef41Sopenharmony_ci
9971cb0ef41Sopenharmony_ci  {
9981cb0ef41Sopenharmony_ci    // Park main thread here to be in the same state as background threads.
9991cb0ef41Sopenharmony_ci    ParkedScope parked_scope(isolate->main_thread_local_isolate());
10001cb0ef41Sopenharmony_ci    if (job->ExecuteJob(isolate->counters()->runtime_call_stats(),
10011cb0ef41Sopenharmony_ci                        isolate->main_thread_local_isolate())) {
10021cb0ef41Sopenharmony_ci      UnparkedScope unparked_scope(isolate->main_thread_local_isolate());
10031cb0ef41Sopenharmony_ci      CompilerTracer::TraceAbortedJob(isolate, compilation_info);
10041cb0ef41Sopenharmony_ci      return false;
10051cb0ef41Sopenharmony_ci    }
10061cb0ef41Sopenharmony_ci  }
10071cb0ef41Sopenharmony_ci
10081cb0ef41Sopenharmony_ci  if (job->FinalizeJob(isolate) != CompilationJob::SUCCEEDED) {
10091cb0ef41Sopenharmony_ci    CompilerTracer::TraceAbortedJob(isolate, compilation_info);
10101cb0ef41Sopenharmony_ci    return false;
10111cb0ef41Sopenharmony_ci  }
10121cb0ef41Sopenharmony_ci
10131cb0ef41Sopenharmony_ci  // Success!
10141cb0ef41Sopenharmony_ci  job->RecordCompilationStats(ConcurrencyMode::kSynchronous, isolate);
10151cb0ef41Sopenharmony_ci  DCHECK(!isolate->has_pending_exception());
10161cb0ef41Sopenharmony_ci  OptimizedCodeCache::Insert(compilation_info);
10171cb0ef41Sopenharmony_ci  job->RecordFunctionCompilation(CodeEventListener::LAZY_COMPILE_TAG, isolate);
10181cb0ef41Sopenharmony_ci  return true;
10191cb0ef41Sopenharmony_ci}
10201cb0ef41Sopenharmony_ci
10211cb0ef41Sopenharmony_cibool CompileTurbofan_Concurrent(Isolate* isolate,
10221cb0ef41Sopenharmony_ci                                std::unique_ptr<TurbofanCompilationJob> job) {
10231cb0ef41Sopenharmony_ci  OptimizedCompilationInfo* const compilation_info = job->compilation_info();
10241cb0ef41Sopenharmony_ci  DCHECK_EQ(compilation_info->code_kind(), CodeKind::TURBOFAN);
10251cb0ef41Sopenharmony_ci  Handle<JSFunction> function = compilation_info->closure();
10261cb0ef41Sopenharmony_ci
10271cb0ef41Sopenharmony_ci  if (!isolate->optimizing_compile_dispatcher()->IsQueueAvailable()) {
10281cb0ef41Sopenharmony_ci    if (FLAG_trace_concurrent_recompilation) {
10291cb0ef41Sopenharmony_ci      PrintF("  ** Compilation queue full, will retry optimizing ");
10301cb0ef41Sopenharmony_ci      function->ShortPrint();
10311cb0ef41Sopenharmony_ci      PrintF(" later.\n");
10321cb0ef41Sopenharmony_ci    }
10331cb0ef41Sopenharmony_ci    return false;
10341cb0ef41Sopenharmony_ci  }
10351cb0ef41Sopenharmony_ci
10361cb0ef41Sopenharmony_ci  if (isolate->heap()->HighMemoryPressure()) {
10371cb0ef41Sopenharmony_ci    if (FLAG_trace_concurrent_recompilation) {
10381cb0ef41Sopenharmony_ci      PrintF("  ** High memory pressure, will retry optimizing ");
10391cb0ef41Sopenharmony_ci      function->ShortPrint();
10401cb0ef41Sopenharmony_ci      PrintF(" later.\n");
10411cb0ef41Sopenharmony_ci    }
10421cb0ef41Sopenharmony_ci    return false;
10431cb0ef41Sopenharmony_ci  }
10441cb0ef41Sopenharmony_ci
10451cb0ef41Sopenharmony_ci  TimerEventScope<TimerEventRecompileSynchronous> timer(isolate);
10461cb0ef41Sopenharmony_ci  RCS_SCOPE(isolate, RuntimeCallCounterId::kOptimizeConcurrentPrepare);
10471cb0ef41Sopenharmony_ci  TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.compile"),
10481cb0ef41Sopenharmony_ci               "V8.OptimizeConcurrentPrepare");
10491cb0ef41Sopenharmony_ci
10501cb0ef41Sopenharmony_ci  if (!PrepareJobWithHandleScope(job.get(), isolate, compilation_info)) {
10511cb0ef41Sopenharmony_ci    return false;
10521cb0ef41Sopenharmony_ci  }
10531cb0ef41Sopenharmony_ci
10541cb0ef41Sopenharmony_ci  // The background recompile will own this job.
10551cb0ef41Sopenharmony_ci  isolate->optimizing_compile_dispatcher()->QueueForOptimization(job.release());
10561cb0ef41Sopenharmony_ci
10571cb0ef41Sopenharmony_ci  if (FLAG_trace_concurrent_recompilation) {
10581cb0ef41Sopenharmony_ci    PrintF("  ** Queued ");
10591cb0ef41Sopenharmony_ci    function->ShortPrint();
10601cb0ef41Sopenharmony_ci    PrintF(" for concurrent optimization.\n");
10611cb0ef41Sopenharmony_ci  }
10621cb0ef41Sopenharmony_ci
10631cb0ef41Sopenharmony_ci  SetTieringState(*function, compilation_info->osr_offset(),
10641cb0ef41Sopenharmony_ci                  TieringState::kInProgress);
10651cb0ef41Sopenharmony_ci
10661cb0ef41Sopenharmony_ci  DCHECK(compilation_info->shared_info()->HasBytecodeArray());
10671cb0ef41Sopenharmony_ci  return true;
10681cb0ef41Sopenharmony_ci}
10691cb0ef41Sopenharmony_ci
10701cb0ef41Sopenharmony_cienum class CompileResultBehavior {
10711cb0ef41Sopenharmony_ci  // Default behavior, i.e. install the result, insert into caches, etc.
10721cb0ef41Sopenharmony_ci  kDefault,
10731cb0ef41Sopenharmony_ci  // Used only for stress testing. The compilation result should be discarded.
10741cb0ef41Sopenharmony_ci  kDiscardForTesting,
10751cb0ef41Sopenharmony_ci};
10761cb0ef41Sopenharmony_ci
10771cb0ef41Sopenharmony_cibool ShouldOptimize(CodeKind code_kind, Handle<SharedFunctionInfo> shared) {
10781cb0ef41Sopenharmony_ci  DCHECK(CodeKindIsOptimizedJSFunction(code_kind));
10791cb0ef41Sopenharmony_ci  switch (code_kind) {
10801cb0ef41Sopenharmony_ci    case CodeKind::TURBOFAN:
10811cb0ef41Sopenharmony_ci      return FLAG_opt && shared->PassesFilter(FLAG_turbo_filter);
10821cb0ef41Sopenharmony_ci    case CodeKind::MAGLEV:
10831cb0ef41Sopenharmony_ci      // TODO(v8:7700): FLAG_maglev_filter.
10841cb0ef41Sopenharmony_ci      return FLAG_maglev;
10851cb0ef41Sopenharmony_ci    default:
10861cb0ef41Sopenharmony_ci      UNREACHABLE();
10871cb0ef41Sopenharmony_ci  }
10881cb0ef41Sopenharmony_ci}
10891cb0ef41Sopenharmony_ci
10901cb0ef41Sopenharmony_ciMaybeHandle<CodeT> CompileTurbofan(Isolate* isolate,
10911cb0ef41Sopenharmony_ci                                   Handle<JSFunction> function,
10921cb0ef41Sopenharmony_ci                                   Handle<SharedFunctionInfo> shared,
10931cb0ef41Sopenharmony_ci                                   ConcurrencyMode mode,
10941cb0ef41Sopenharmony_ci                                   BytecodeOffset osr_offset,
10951cb0ef41Sopenharmony_ci                                   JavaScriptFrame* osr_frame,
10961cb0ef41Sopenharmony_ci                                   CompileResultBehavior result_behavior) {
10971cb0ef41Sopenharmony_ci  VMState<COMPILER> state(isolate);
10981cb0ef41Sopenharmony_ci  TimerEventScope<TimerEventOptimizeCode> optimize_code_timer(isolate);
10991cb0ef41Sopenharmony_ci  RCS_SCOPE(isolate, RuntimeCallCounterId::kOptimizeCode);
11001cb0ef41Sopenharmony_ci  TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.compile"), "V8.OptimizeCode");
11011cb0ef41Sopenharmony_ci
11021cb0ef41Sopenharmony_ci  DCHECK(!isolate->has_pending_exception());
11031cb0ef41Sopenharmony_ci  PostponeInterruptsScope postpone(isolate);
11041cb0ef41Sopenharmony_ci  bool has_script = shared->script().IsScript();
11051cb0ef41Sopenharmony_ci  // BUG(5946): This DCHECK is necessary to make certain that we won't
11061cb0ef41Sopenharmony_ci  // tolerate the lack of a script without bytecode.
11071cb0ef41Sopenharmony_ci  DCHECK_IMPLIES(!has_script, shared->HasBytecodeArray());
11081cb0ef41Sopenharmony_ci  std::unique_ptr<TurbofanCompilationJob> job(
11091cb0ef41Sopenharmony_ci      compiler::Pipeline::NewCompilationJob(isolate, function,
11101cb0ef41Sopenharmony_ci                                            CodeKind::TURBOFAN, has_script,
11111cb0ef41Sopenharmony_ci                                            osr_offset, osr_frame));
11121cb0ef41Sopenharmony_ci
11131cb0ef41Sopenharmony_ci  if (result_behavior == CompileResultBehavior::kDiscardForTesting) {
11141cb0ef41Sopenharmony_ci    job->compilation_info()->set_discard_result_for_testing();
11151cb0ef41Sopenharmony_ci  }
11161cb0ef41Sopenharmony_ci
11171cb0ef41Sopenharmony_ci  // Prepare the job and launch concurrent compilation, or compile now.
11181cb0ef41Sopenharmony_ci  if (IsConcurrent(mode)) {
11191cb0ef41Sopenharmony_ci    if (CompileTurbofan_Concurrent(isolate, std::move(job))) return {};
11201cb0ef41Sopenharmony_ci  } else {
11211cb0ef41Sopenharmony_ci    DCHECK(IsSynchronous(mode));
11221cb0ef41Sopenharmony_ci    if (CompileTurbofan_NotConcurrent(isolate, job.get())) {
11231cb0ef41Sopenharmony_ci      return ToCodeT(job->compilation_info()->code(), isolate);
11241cb0ef41Sopenharmony_ci    }
11251cb0ef41Sopenharmony_ci  }
11261cb0ef41Sopenharmony_ci
11271cb0ef41Sopenharmony_ci  if (isolate->has_pending_exception()) isolate->clear_pending_exception();
11281cb0ef41Sopenharmony_ci  return {};
11291cb0ef41Sopenharmony_ci}
11301cb0ef41Sopenharmony_ci
11311cb0ef41Sopenharmony_ci#ifdef V8_ENABLE_MAGLEV
11321cb0ef41Sopenharmony_ci// TODO(v8:7700): Record maglev compilations better.
11331cb0ef41Sopenharmony_civoid RecordMaglevFunctionCompilation(Isolate* isolate,
11341cb0ef41Sopenharmony_ci                                     Handle<JSFunction> function) {
11351cb0ef41Sopenharmony_ci  Handle<AbstractCode> abstract_code(
11361cb0ef41Sopenharmony_ci      AbstractCode::cast(FromCodeT(function->code())), isolate);
11371cb0ef41Sopenharmony_ci  Handle<SharedFunctionInfo> shared(function->shared(), isolate);
11381cb0ef41Sopenharmony_ci  Handle<Script> script(Script::cast(shared->script()), isolate);
11391cb0ef41Sopenharmony_ci  Handle<FeedbackVector> feedback_vector(function->feedback_vector(), isolate);
11401cb0ef41Sopenharmony_ci
11411cb0ef41Sopenharmony_ci  // Optimistic estimate.
11421cb0ef41Sopenharmony_ci  double time_taken_ms = 0;
11431cb0ef41Sopenharmony_ci
11441cb0ef41Sopenharmony_ci  LogFunctionCompilation(isolate, CodeEventListener::FUNCTION_TAG, script,
11451cb0ef41Sopenharmony_ci                         shared, feedback_vector, abstract_code,
11461cb0ef41Sopenharmony_ci                         abstract_code->kind(), time_taken_ms);
11471cb0ef41Sopenharmony_ci}
11481cb0ef41Sopenharmony_ci#endif  // V8_ENABLE_MAGLEV
11491cb0ef41Sopenharmony_ci
11501cb0ef41Sopenharmony_ciMaybeHandle<CodeT> CompileMaglev(Isolate* isolate, Handle<JSFunction> function,
11511cb0ef41Sopenharmony_ci                                 ConcurrencyMode mode,
11521cb0ef41Sopenharmony_ci                                 BytecodeOffset osr_offset,
11531cb0ef41Sopenharmony_ci                                 JavaScriptFrame* osr_frame,
11541cb0ef41Sopenharmony_ci                                 CompileResultBehavior result_behavior) {
11551cb0ef41Sopenharmony_ci#ifdef V8_ENABLE_MAGLEV
11561cb0ef41Sopenharmony_ci  DCHECK(FLAG_maglev);
11571cb0ef41Sopenharmony_ci  // TODO(v8:7700): Add missing support.
11581cb0ef41Sopenharmony_ci  CHECK(!IsOSR(osr_offset));
11591cb0ef41Sopenharmony_ci  CHECK(osr_frame == nullptr);
11601cb0ef41Sopenharmony_ci  CHECK(result_behavior == CompileResultBehavior::kDefault);
11611cb0ef41Sopenharmony_ci
11621cb0ef41Sopenharmony_ci  // TODO(v8:7700): Tracing, see CompileTurbofan.
11631cb0ef41Sopenharmony_ci
11641cb0ef41Sopenharmony_ci  DCHECK(!isolate->has_pending_exception());
11651cb0ef41Sopenharmony_ci  PostponeInterruptsScope postpone(isolate);
11661cb0ef41Sopenharmony_ci
11671cb0ef41Sopenharmony_ci  // TODO(v8:7700): See everything in CompileTurbofan_Concurrent.
11681cb0ef41Sopenharmony_ci  // - Tracing,
11691cb0ef41Sopenharmony_ci  // - timers,
11701cb0ef41Sopenharmony_ci  // - aborts on memory pressure,
11711cb0ef41Sopenharmony_ci  // ...
11721cb0ef41Sopenharmony_ci
11731cb0ef41Sopenharmony_ci  // Prepare the job.
11741cb0ef41Sopenharmony_ci  auto job = maglev::MaglevCompilationJob::New(isolate, function);
11751cb0ef41Sopenharmony_ci  CompilationJob::Status status = job->PrepareJob(isolate);
11761cb0ef41Sopenharmony_ci  CHECK_EQ(status, CompilationJob::SUCCEEDED);  // TODO(v8:7700): Use status.
11771cb0ef41Sopenharmony_ci
11781cb0ef41Sopenharmony_ci  if (IsSynchronous(mode)) {
11791cb0ef41Sopenharmony_ci    function->reset_tiering_state();
11801cb0ef41Sopenharmony_ci    {
11811cb0ef41Sopenharmony_ci      // Park the main thread Isolate here, to be in the same state as
11821cb0ef41Sopenharmony_ci      // background threads.
11831cb0ef41Sopenharmony_ci      ParkedScope parked_scope(isolate->main_thread_local_isolate());
11841cb0ef41Sopenharmony_ci      if (job->ExecuteJob(isolate->counters()->runtime_call_stats(),
11851cb0ef41Sopenharmony_ci                          isolate->main_thread_local_isolate()) !=
11861cb0ef41Sopenharmony_ci          CompilationJob::SUCCEEDED) {
11871cb0ef41Sopenharmony_ci        return {};
11881cb0ef41Sopenharmony_ci      }
11891cb0ef41Sopenharmony_ci    }
11901cb0ef41Sopenharmony_ci
11911cb0ef41Sopenharmony_ci    if (job->FinalizeJob(isolate) != CompilationJob::SUCCEEDED) {
11921cb0ef41Sopenharmony_ci      return {};
11931cb0ef41Sopenharmony_ci    }
11941cb0ef41Sopenharmony_ci
11951cb0ef41Sopenharmony_ci    RecordMaglevFunctionCompilation(isolate, function);
11961cb0ef41Sopenharmony_ci    return handle(function->code(), isolate);
11971cb0ef41Sopenharmony_ci  }
11981cb0ef41Sopenharmony_ci
11991cb0ef41Sopenharmony_ci  DCHECK(IsConcurrent(mode));
12001cb0ef41Sopenharmony_ci
12011cb0ef41Sopenharmony_ci  // Enqueue it.
12021cb0ef41Sopenharmony_ci  isolate->maglev_concurrent_dispatcher()->EnqueueJob(std::move(job));
12031cb0ef41Sopenharmony_ci
12041cb0ef41Sopenharmony_ci  // Remember that the function is currently being processed.
12051cb0ef41Sopenharmony_ci  SetTieringState(*function, osr_offset, TieringState::kInProgress);
12061cb0ef41Sopenharmony_ci
12071cb0ef41Sopenharmony_ci  return {};
12081cb0ef41Sopenharmony_ci#else   // V8_ENABLE_MAGLEV
12091cb0ef41Sopenharmony_ci  UNREACHABLE();
12101cb0ef41Sopenharmony_ci#endif  // V8_ENABLE_MAGLEV
12111cb0ef41Sopenharmony_ci}
12121cb0ef41Sopenharmony_ci
12131cb0ef41Sopenharmony_ciMaybeHandle<CodeT> GetOrCompileOptimized(
12141cb0ef41Sopenharmony_ci    Isolate* isolate, Handle<JSFunction> function, ConcurrencyMode mode,
12151cb0ef41Sopenharmony_ci    CodeKind code_kind, BytecodeOffset osr_offset = BytecodeOffset::None(),
12161cb0ef41Sopenharmony_ci    JavaScriptFrame* osr_frame = nullptr,
12171cb0ef41Sopenharmony_ci    CompileResultBehavior result_behavior = CompileResultBehavior::kDefault) {
12181cb0ef41Sopenharmony_ci  DCHECK(CodeKindIsOptimizedJSFunction(code_kind));
12191cb0ef41Sopenharmony_ci
12201cb0ef41Sopenharmony_ci  Handle<SharedFunctionInfo> shared(function->shared(), isolate);
12211cb0ef41Sopenharmony_ci
12221cb0ef41Sopenharmony_ci  // Clear the optimization marker on the function so that we don't try to
12231cb0ef41Sopenharmony_ci  // re-optimize.
12241cb0ef41Sopenharmony_ci  if (!IsOSR(osr_offset)) {
12251cb0ef41Sopenharmony_ci    ResetTieringState(*function, osr_offset);
12261cb0ef41Sopenharmony_ci  }
12271cb0ef41Sopenharmony_ci
12281cb0ef41Sopenharmony_ci  // TODO(v8:7700): Distinguish between Maglev and Turbofan.
12291cb0ef41Sopenharmony_ci  if (shared->optimization_disabled() &&
12301cb0ef41Sopenharmony_ci      shared->disabled_optimization_reason() == BailoutReason::kNeverOptimize) {
12311cb0ef41Sopenharmony_ci    return {};
12321cb0ef41Sopenharmony_ci  }
12331cb0ef41Sopenharmony_ci
12341cb0ef41Sopenharmony_ci  // Do not optimize when debugger needs to hook into every call.
12351cb0ef41Sopenharmony_ci  if (isolate->debug()->needs_check_on_function_call()) return {};
12361cb0ef41Sopenharmony_ci
12371cb0ef41Sopenharmony_ci  // Do not optimize if we need to be able to set break points.
12381cb0ef41Sopenharmony_ci  if (shared->HasBreakInfo()) return {};
12391cb0ef41Sopenharmony_ci
12401cb0ef41Sopenharmony_ci  // Do not optimize if optimization is disabled or function doesn't pass
12411cb0ef41Sopenharmony_ci  // turbo_filter.
12421cb0ef41Sopenharmony_ci  if (!ShouldOptimize(code_kind, shared)) return {};
12431cb0ef41Sopenharmony_ci
12441cb0ef41Sopenharmony_ci  // If code was pending optimization for testing, remove the entry from the
12451cb0ef41Sopenharmony_ci  // table that was preventing the bytecode from being flushed.
12461cb0ef41Sopenharmony_ci  if (V8_UNLIKELY(FLAG_testing_d8_test_runner)) {
12471cb0ef41Sopenharmony_ci    PendingOptimizationTable::FunctionWasOptimized(isolate, function);
12481cb0ef41Sopenharmony_ci  }
12491cb0ef41Sopenharmony_ci
12501cb0ef41Sopenharmony_ci  Handle<CodeT> cached_code;
12511cb0ef41Sopenharmony_ci  if (OptimizedCodeCache::Get(isolate, function, osr_offset, code_kind)
12521cb0ef41Sopenharmony_ci          .ToHandle(&cached_code)) {
12531cb0ef41Sopenharmony_ci    return cached_code;
12541cb0ef41Sopenharmony_ci  }
12551cb0ef41Sopenharmony_ci
12561cb0ef41Sopenharmony_ci  DCHECK(shared->is_compiled());
12571cb0ef41Sopenharmony_ci
12581cb0ef41Sopenharmony_ci  ResetProfilerTicks(*function, osr_offset);
12591cb0ef41Sopenharmony_ci
12601cb0ef41Sopenharmony_ci  if (code_kind == CodeKind::TURBOFAN) {
12611cb0ef41Sopenharmony_ci    return CompileTurbofan(isolate, function, shared, mode, osr_offset,
12621cb0ef41Sopenharmony_ci                           osr_frame, result_behavior);
12631cb0ef41Sopenharmony_ci  } else {
12641cb0ef41Sopenharmony_ci    DCHECK_EQ(code_kind, CodeKind::MAGLEV);
12651cb0ef41Sopenharmony_ci    return CompileMaglev(isolate, function, mode, osr_offset, osr_frame,
12661cb0ef41Sopenharmony_ci                         result_behavior);
12671cb0ef41Sopenharmony_ci  }
12681cb0ef41Sopenharmony_ci}
12691cb0ef41Sopenharmony_ci
12701cb0ef41Sopenharmony_ci// When --stress-concurrent-inlining is enabled, spawn concurrent jobs in
12711cb0ef41Sopenharmony_ci// addition to non-concurrent compiles to increase coverage in mjsunit tests
12721cb0ef41Sopenharmony_ci// (where most interesting compiles are non-concurrent). The result of the
12731cb0ef41Sopenharmony_ci// compilation is thrown out.
12741cb0ef41Sopenharmony_civoid SpawnDuplicateConcurrentJobForStressTesting(Isolate* isolate,
12751cb0ef41Sopenharmony_ci                                                 Handle<JSFunction> function,
12761cb0ef41Sopenharmony_ci                                                 ConcurrencyMode mode,
12771cb0ef41Sopenharmony_ci                                                 CodeKind code_kind) {
12781cb0ef41Sopenharmony_ci  // TODO(v8:7700): Support Maglev.
12791cb0ef41Sopenharmony_ci  if (code_kind == CodeKind::MAGLEV) return;
12801cb0ef41Sopenharmony_ci
12811cb0ef41Sopenharmony_ci  DCHECK(FLAG_stress_concurrent_inlining &&
12821cb0ef41Sopenharmony_ci         isolate->concurrent_recompilation_enabled() && IsSynchronous(mode) &&
12831cb0ef41Sopenharmony_ci         isolate->node_observer() == nullptr);
12841cb0ef41Sopenharmony_ci  CompileResultBehavior result_behavior =
12851cb0ef41Sopenharmony_ci      FLAG_stress_concurrent_inlining_attach_code
12861cb0ef41Sopenharmony_ci          ? CompileResultBehavior::kDefault
12871cb0ef41Sopenharmony_ci          : CompileResultBehavior::kDiscardForTesting;
12881cb0ef41Sopenharmony_ci  USE(GetOrCompileOptimized(isolate, function, ConcurrencyMode::kConcurrent,
12891cb0ef41Sopenharmony_ci                            code_kind, BytecodeOffset::None(), nullptr,
12901cb0ef41Sopenharmony_ci                            result_behavior));
12911cb0ef41Sopenharmony_ci}
12921cb0ef41Sopenharmony_ci
12931cb0ef41Sopenharmony_cibool FailAndClearPendingException(Isolate* isolate) {
12941cb0ef41Sopenharmony_ci  isolate->clear_pending_exception();
12951cb0ef41Sopenharmony_ci  return false;
12961cb0ef41Sopenharmony_ci}
12971cb0ef41Sopenharmony_ci
12981cb0ef41Sopenharmony_citemplate <typename IsolateT>
12991cb0ef41Sopenharmony_cibool PreparePendingException(IsolateT* isolate, ParseInfo* parse_info) {
13001cb0ef41Sopenharmony_ci  if (parse_info->pending_error_handler()->has_pending_error()) {
13011cb0ef41Sopenharmony_ci    parse_info->pending_error_handler()->PrepareErrors(
13021cb0ef41Sopenharmony_ci        isolate, parse_info->ast_value_factory());
13031cb0ef41Sopenharmony_ci  }
13041cb0ef41Sopenharmony_ci  return false;
13051cb0ef41Sopenharmony_ci}
13061cb0ef41Sopenharmony_ci
13071cb0ef41Sopenharmony_cibool FailWithPreparedPendingException(
13081cb0ef41Sopenharmony_ci    Isolate* isolate, Handle<Script> script,
13091cb0ef41Sopenharmony_ci    const PendingCompilationErrorHandler* pending_error_handler,
13101cb0ef41Sopenharmony_ci    Compiler::ClearExceptionFlag flag = Compiler::KEEP_EXCEPTION) {
13111cb0ef41Sopenharmony_ci  if (flag == Compiler::CLEAR_EXCEPTION) {
13121cb0ef41Sopenharmony_ci    return FailAndClearPendingException(isolate);
13131cb0ef41Sopenharmony_ci  }
13141cb0ef41Sopenharmony_ci
13151cb0ef41Sopenharmony_ci  if (!isolate->has_pending_exception()) {
13161cb0ef41Sopenharmony_ci    if (pending_error_handler->has_pending_error()) {
13171cb0ef41Sopenharmony_ci      pending_error_handler->ReportErrors(isolate, script);
13181cb0ef41Sopenharmony_ci    } else {
13191cb0ef41Sopenharmony_ci      isolate->StackOverflow();
13201cb0ef41Sopenharmony_ci    }
13211cb0ef41Sopenharmony_ci  }
13221cb0ef41Sopenharmony_ci  return false;
13231cb0ef41Sopenharmony_ci}
13241cb0ef41Sopenharmony_ci
13251cb0ef41Sopenharmony_cibool FailWithPendingException(Isolate* isolate, Handle<Script> script,
13261cb0ef41Sopenharmony_ci                              ParseInfo* parse_info,
13271cb0ef41Sopenharmony_ci                              Compiler::ClearExceptionFlag flag) {
13281cb0ef41Sopenharmony_ci  PreparePendingException(isolate, parse_info);
13291cb0ef41Sopenharmony_ci  return FailWithPreparedPendingException(
13301cb0ef41Sopenharmony_ci      isolate, script, parse_info->pending_error_handler(), flag);
13311cb0ef41Sopenharmony_ci}
13321cb0ef41Sopenharmony_ci
13331cb0ef41Sopenharmony_civoid FinalizeUnoptimizedCompilation(
13341cb0ef41Sopenharmony_ci    Isolate* isolate, Handle<Script> script,
13351cb0ef41Sopenharmony_ci    const UnoptimizedCompileFlags& flags,
13361cb0ef41Sopenharmony_ci    const UnoptimizedCompileState* compile_state,
13371cb0ef41Sopenharmony_ci    const FinalizeUnoptimizedCompilationDataList&
13381cb0ef41Sopenharmony_ci        finalize_unoptimized_compilation_data_list) {
13391cb0ef41Sopenharmony_ci  if (compile_state->pending_error_handler()->has_pending_warnings()) {
13401cb0ef41Sopenharmony_ci    compile_state->pending_error_handler()->ReportWarnings(isolate, script);
13411cb0ef41Sopenharmony_ci  }
13421cb0ef41Sopenharmony_ci
13431cb0ef41Sopenharmony_ci  bool need_source_positions = FLAG_stress_lazy_source_positions ||
13441cb0ef41Sopenharmony_ci                               (!flags.collect_source_positions() &&
13451cb0ef41Sopenharmony_ci                                isolate->NeedsSourcePositionsForProfiling());
13461cb0ef41Sopenharmony_ci
13471cb0ef41Sopenharmony_ci  for (const auto& finalize_data : finalize_unoptimized_compilation_data_list) {
13481cb0ef41Sopenharmony_ci    Handle<SharedFunctionInfo> shared_info = finalize_data.function_handle();
13491cb0ef41Sopenharmony_ci    // It's unlikely, but possible, that the bytecode was flushed between being
13501cb0ef41Sopenharmony_ci    // allocated and now, so guard against that case, and against it being
13511cb0ef41Sopenharmony_ci    // flushed in the middle of this loop.
13521cb0ef41Sopenharmony_ci    IsCompiledScope is_compiled_scope(*shared_info, isolate);
13531cb0ef41Sopenharmony_ci    if (!is_compiled_scope.is_compiled()) continue;
13541cb0ef41Sopenharmony_ci
13551cb0ef41Sopenharmony_ci    if (need_source_positions) {
13561cb0ef41Sopenharmony_ci      SharedFunctionInfo::EnsureSourcePositionsAvailable(isolate, shared_info);
13571cb0ef41Sopenharmony_ci    }
13581cb0ef41Sopenharmony_ci    CodeEventListener::LogEventsAndTags log_tag;
13591cb0ef41Sopenharmony_ci    if (shared_info->is_toplevel()) {
13601cb0ef41Sopenharmony_ci      log_tag = flags.is_eval() ? CodeEventListener::EVAL_TAG
13611cb0ef41Sopenharmony_ci                                : CodeEventListener::SCRIPT_TAG;
13621cb0ef41Sopenharmony_ci    } else {
13631cb0ef41Sopenharmony_ci      log_tag = flags.is_lazy_compile() ? CodeEventListener::LAZY_COMPILE_TAG
13641cb0ef41Sopenharmony_ci                                        : CodeEventListener::FUNCTION_TAG;
13651cb0ef41Sopenharmony_ci    }
13661cb0ef41Sopenharmony_ci    log_tag = Logger::ToNativeByScript(log_tag, *script);
13671cb0ef41Sopenharmony_ci    if (FLAG_interpreted_frames_native_stack) {
13681cb0ef41Sopenharmony_ci      InstallInterpreterTrampolineCopy(isolate, shared_info, log_tag);
13691cb0ef41Sopenharmony_ci    }
13701cb0ef41Sopenharmony_ci    Handle<CoverageInfo> coverage_info;
13711cb0ef41Sopenharmony_ci    if (finalize_data.coverage_info().ToHandle(&coverage_info)) {
13721cb0ef41Sopenharmony_ci      isolate->debug()->InstallCoverageInfo(shared_info, coverage_info);
13731cb0ef41Sopenharmony_ci    }
13741cb0ef41Sopenharmony_ci
13751cb0ef41Sopenharmony_ci    LogUnoptimizedCompilation(isolate, shared_info, log_tag,
13761cb0ef41Sopenharmony_ci                              finalize_data.time_taken_to_execute(),
13771cb0ef41Sopenharmony_ci                              finalize_data.time_taken_to_finalize());
13781cb0ef41Sopenharmony_ci  }
13791cb0ef41Sopenharmony_ci}
13801cb0ef41Sopenharmony_ci
13811cb0ef41Sopenharmony_civoid FinalizeUnoptimizedScriptCompilation(
13821cb0ef41Sopenharmony_ci    Isolate* isolate, Handle<Script> script,
13831cb0ef41Sopenharmony_ci    const UnoptimizedCompileFlags& flags,
13841cb0ef41Sopenharmony_ci    const UnoptimizedCompileState* compile_state,
13851cb0ef41Sopenharmony_ci    const FinalizeUnoptimizedCompilationDataList&
13861cb0ef41Sopenharmony_ci        finalize_unoptimized_compilation_data_list) {
13871cb0ef41Sopenharmony_ci  FinalizeUnoptimizedCompilation(isolate, script, flags, compile_state,
13881cb0ef41Sopenharmony_ci                                 finalize_unoptimized_compilation_data_list);
13891cb0ef41Sopenharmony_ci
13901cb0ef41Sopenharmony_ci  script->set_compilation_state(Script::COMPILATION_STATE_COMPILED);
13911cb0ef41Sopenharmony_ci
13921cb0ef41Sopenharmony_ci  if (isolate->NeedsSourcePositionsForProfiling()) {
13931cb0ef41Sopenharmony_ci    Script::InitLineEnds(isolate, script);
13941cb0ef41Sopenharmony_ci  }
13951cb0ef41Sopenharmony_ci}
13961cb0ef41Sopenharmony_ci
13971cb0ef41Sopenharmony_civoid CompileAllWithBaseline(Isolate* isolate,
13981cb0ef41Sopenharmony_ci                            const FinalizeUnoptimizedCompilationDataList&
13991cb0ef41Sopenharmony_ci                                finalize_unoptimized_compilation_data_list) {
14001cb0ef41Sopenharmony_ci  CodePageCollectionMemoryModificationScope code_allocation(isolate->heap());
14011cb0ef41Sopenharmony_ci  for (const auto& finalize_data : finalize_unoptimized_compilation_data_list) {
14021cb0ef41Sopenharmony_ci    Handle<SharedFunctionInfo> shared_info = finalize_data.function_handle();
14031cb0ef41Sopenharmony_ci    IsCompiledScope is_compiled_scope(*shared_info, isolate);
14041cb0ef41Sopenharmony_ci    if (!is_compiled_scope.is_compiled()) continue;
14051cb0ef41Sopenharmony_ci    if (!CanCompileWithBaseline(isolate, *shared_info)) continue;
14061cb0ef41Sopenharmony_ci    Compiler::CompileSharedWithBaseline(
14071cb0ef41Sopenharmony_ci        isolate, shared_info, Compiler::CLEAR_EXCEPTION, &is_compiled_scope);
14081cb0ef41Sopenharmony_ci  }
14091cb0ef41Sopenharmony_ci}
14101cb0ef41Sopenharmony_ci
14111cb0ef41Sopenharmony_ci// Create shared function info for top level and shared function infos array for
14121cb0ef41Sopenharmony_ci// inner functions.
14131cb0ef41Sopenharmony_citemplate <typename IsolateT>
14141cb0ef41Sopenharmony_ciHandle<SharedFunctionInfo> CreateTopLevelSharedFunctionInfo(
14151cb0ef41Sopenharmony_ci    ParseInfo* parse_info, Handle<Script> script, IsolateT* isolate) {
14161cb0ef41Sopenharmony_ci  EnsureSharedFunctionInfosArrayOnScript(script, parse_info, isolate);
14171cb0ef41Sopenharmony_ci  DCHECK_EQ(kNoSourcePosition,
14181cb0ef41Sopenharmony_ci            parse_info->literal()->function_token_position());
14191cb0ef41Sopenharmony_ci  return isolate->factory()->NewSharedFunctionInfoForLiteral(
14201cb0ef41Sopenharmony_ci      parse_info->literal(), script, true);
14211cb0ef41Sopenharmony_ci}
14221cb0ef41Sopenharmony_ci
14231cb0ef41Sopenharmony_ciMaybeHandle<SharedFunctionInfo> CompileToplevel(
14241cb0ef41Sopenharmony_ci    ParseInfo* parse_info, Handle<Script> script,
14251cb0ef41Sopenharmony_ci    MaybeHandle<ScopeInfo> maybe_outer_scope_info, Isolate* isolate,
14261cb0ef41Sopenharmony_ci    IsCompiledScope* is_compiled_scope) {
14271cb0ef41Sopenharmony_ci  TimerEventScope<TimerEventCompileCode> top_level_timer(isolate);
14281cb0ef41Sopenharmony_ci  TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.compile"), "V8.CompileCode");
14291cb0ef41Sopenharmony_ci  DCHECK_EQ(ThreadId::Current(), isolate->thread_id());
14301cb0ef41Sopenharmony_ci
14311cb0ef41Sopenharmony_ci  PostponeInterruptsScope postpone(isolate);
14321cb0ef41Sopenharmony_ci  DCHECK(!isolate->native_context().is_null());
14331cb0ef41Sopenharmony_ci  RCS_SCOPE(isolate, parse_info->flags().is_eval()
14341cb0ef41Sopenharmony_ci                         ? RuntimeCallCounterId::kCompileEval
14351cb0ef41Sopenharmony_ci                         : RuntimeCallCounterId::kCompileScript);
14361cb0ef41Sopenharmony_ci  VMState<BYTECODE_COMPILER> state(isolate);
14371cb0ef41Sopenharmony_ci  if (parse_info->literal() == nullptr &&
14381cb0ef41Sopenharmony_ci      !parsing::ParseProgram(parse_info, script, maybe_outer_scope_info,
14391cb0ef41Sopenharmony_ci                             isolate, parsing::ReportStatisticsMode::kYes)) {
14401cb0ef41Sopenharmony_ci    FailWithPendingException(isolate, script, parse_info,
14411cb0ef41Sopenharmony_ci                             Compiler::ClearExceptionFlag::KEEP_EXCEPTION);
14421cb0ef41Sopenharmony_ci    return MaybeHandle<SharedFunctionInfo>();
14431cb0ef41Sopenharmony_ci  }
14441cb0ef41Sopenharmony_ci  // Measure how long it takes to do the compilation; only take the
14451cb0ef41Sopenharmony_ci  // rest of the function into account to avoid overlap with the
14461cb0ef41Sopenharmony_ci  // parsing statistics.
14471cb0ef41Sopenharmony_ci  NestedTimedHistogram* rate = parse_info->flags().is_eval()
14481cb0ef41Sopenharmony_ci                                   ? isolate->counters()->compile_eval()
14491cb0ef41Sopenharmony_ci                                   : isolate->counters()->compile();
14501cb0ef41Sopenharmony_ci  NestedTimedHistogramScope timer(rate);
14511cb0ef41Sopenharmony_ci  TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.compile"),
14521cb0ef41Sopenharmony_ci               parse_info->flags().is_eval() ? "V8.CompileEval" : "V8.Compile");
14531cb0ef41Sopenharmony_ci
14541cb0ef41Sopenharmony_ci  // Create the SharedFunctionInfo and add it to the script's list.
14551cb0ef41Sopenharmony_ci  Handle<SharedFunctionInfo> shared_info =
14561cb0ef41Sopenharmony_ci      CreateTopLevelSharedFunctionInfo(parse_info, script, isolate);
14571cb0ef41Sopenharmony_ci
14581cb0ef41Sopenharmony_ci  FinalizeUnoptimizedCompilationDataList
14591cb0ef41Sopenharmony_ci      finalize_unoptimized_compilation_data_list;
14601cb0ef41Sopenharmony_ci
14611cb0ef41Sopenharmony_ci  // Prepare and execute compilation of the outer-most function.
14621cb0ef41Sopenharmony_ci  if (!IterativelyExecuteAndFinalizeUnoptimizedCompilationJobs(
14631cb0ef41Sopenharmony_ci          isolate, shared_info, script, parse_info, isolate->allocator(),
14641cb0ef41Sopenharmony_ci          is_compiled_scope, &finalize_unoptimized_compilation_data_list,
14651cb0ef41Sopenharmony_ci          nullptr)) {
14661cb0ef41Sopenharmony_ci    FailWithPendingException(isolate, script, parse_info,
14671cb0ef41Sopenharmony_ci                             Compiler::ClearExceptionFlag::KEEP_EXCEPTION);
14681cb0ef41Sopenharmony_ci    return MaybeHandle<SharedFunctionInfo>();
14691cb0ef41Sopenharmony_ci  }
14701cb0ef41Sopenharmony_ci
14711cb0ef41Sopenharmony_ci  // Character stream shouldn't be used again.
14721cb0ef41Sopenharmony_ci  parse_info->ResetCharacterStream();
14731cb0ef41Sopenharmony_ci
14741cb0ef41Sopenharmony_ci  FinalizeUnoptimizedScriptCompilation(
14751cb0ef41Sopenharmony_ci      isolate, script, parse_info->flags(), parse_info->state(),
14761cb0ef41Sopenharmony_ci      finalize_unoptimized_compilation_data_list);
14771cb0ef41Sopenharmony_ci
14781cb0ef41Sopenharmony_ci  if (FLAG_always_sparkplug) {
14791cb0ef41Sopenharmony_ci    CompileAllWithBaseline(isolate, finalize_unoptimized_compilation_data_list);
14801cb0ef41Sopenharmony_ci  }
14811cb0ef41Sopenharmony_ci
14821cb0ef41Sopenharmony_ci  return shared_info;
14831cb0ef41Sopenharmony_ci}
14841cb0ef41Sopenharmony_ci
14851cb0ef41Sopenharmony_ci#ifdef V8_RUNTIME_CALL_STATS
14861cb0ef41Sopenharmony_ciRuntimeCallCounterId RuntimeCallCounterIdForCompile(ParseInfo* parse_info) {
14871cb0ef41Sopenharmony_ci  if (parse_info->flags().is_toplevel()) {
14881cb0ef41Sopenharmony_ci    if (parse_info->flags().is_eval()) {
14891cb0ef41Sopenharmony_ci      return RuntimeCallCounterId::kCompileEval;
14901cb0ef41Sopenharmony_ci    }
14911cb0ef41Sopenharmony_ci    return RuntimeCallCounterId::kCompileScript;
14921cb0ef41Sopenharmony_ci  }
14931cb0ef41Sopenharmony_ci  return RuntimeCallCounterId::kCompileFunction;
14941cb0ef41Sopenharmony_ci}
14951cb0ef41Sopenharmony_ci#endif  // V8_RUNTIME_CALL_STATS
14961cb0ef41Sopenharmony_ci
14971cb0ef41Sopenharmony_ci}  // namespace
14981cb0ef41Sopenharmony_ci
14991cb0ef41Sopenharmony_ciCompilationHandleScope::~CompilationHandleScope() {
15001cb0ef41Sopenharmony_ci  info_->set_persistent_handles(persistent_.Detach());
15011cb0ef41Sopenharmony_ci}
15021cb0ef41Sopenharmony_ci
15031cb0ef41Sopenharmony_ciFinalizeUnoptimizedCompilationData::FinalizeUnoptimizedCompilationData(
15041cb0ef41Sopenharmony_ci    LocalIsolate* isolate, Handle<SharedFunctionInfo> function_handle,
15051cb0ef41Sopenharmony_ci    MaybeHandle<CoverageInfo> coverage_info,
15061cb0ef41Sopenharmony_ci    base::TimeDelta time_taken_to_execute,
15071cb0ef41Sopenharmony_ci    base::TimeDelta time_taken_to_finalize)
15081cb0ef41Sopenharmony_ci    : time_taken_to_execute_(time_taken_to_execute),
15091cb0ef41Sopenharmony_ci      time_taken_to_finalize_(time_taken_to_finalize),
15101cb0ef41Sopenharmony_ci      function_handle_(isolate->heap()->NewPersistentHandle(function_handle)),
15111cb0ef41Sopenharmony_ci      coverage_info_(isolate->heap()->NewPersistentMaybeHandle(coverage_info)) {
15121cb0ef41Sopenharmony_ci}
15131cb0ef41Sopenharmony_ci
15141cb0ef41Sopenharmony_ciDeferredFinalizationJobData::DeferredFinalizationJobData(
15151cb0ef41Sopenharmony_ci    LocalIsolate* isolate, Handle<SharedFunctionInfo> function_handle,
15161cb0ef41Sopenharmony_ci    std::unique_ptr<UnoptimizedCompilationJob> job)
15171cb0ef41Sopenharmony_ci    : function_handle_(isolate->heap()->NewPersistentHandle(function_handle)),
15181cb0ef41Sopenharmony_ci      job_(std::move(job)) {}
15191cb0ef41Sopenharmony_ci
15201cb0ef41Sopenharmony_ciBackgroundCompileTask::BackgroundCompileTask(ScriptStreamingData* streamed_data,
15211cb0ef41Sopenharmony_ci                                             Isolate* isolate, ScriptType type)
15221cb0ef41Sopenharmony_ci    : isolate_for_local_isolate_(isolate),
15231cb0ef41Sopenharmony_ci      flags_(UnoptimizedCompileFlags::ForToplevelCompile(
15241cb0ef41Sopenharmony_ci          isolate, true, construct_language_mode(FLAG_use_strict),
15251cb0ef41Sopenharmony_ci          REPLMode::kNo, type, FLAG_lazy_streaming)),
15261cb0ef41Sopenharmony_ci      character_stream_(ScannerStream::For(streamed_data->source_stream.get(),
15271cb0ef41Sopenharmony_ci                                           streamed_data->encoding)),
15281cb0ef41Sopenharmony_ci      stack_size_(i::FLAG_stack_size),
15291cb0ef41Sopenharmony_ci      worker_thread_runtime_call_stats_(
15301cb0ef41Sopenharmony_ci          isolate->counters()->worker_thread_runtime_call_stats()),
15311cb0ef41Sopenharmony_ci      timer_(isolate->counters()->compile_script_on_background()),
15321cb0ef41Sopenharmony_ci      start_position_(0),
15331cb0ef41Sopenharmony_ci      end_position_(0),
15341cb0ef41Sopenharmony_ci      function_literal_id_(kFunctionLiteralIdTopLevel) {
15351cb0ef41Sopenharmony_ci  VMState<PARSER> state(isolate);
15361cb0ef41Sopenharmony_ci
15371cb0ef41Sopenharmony_ci  LOG(isolate, ScriptEvent(Logger::ScriptEventType::kStreamingCompile,
15381cb0ef41Sopenharmony_ci                           flags_.script_id()));
15391cb0ef41Sopenharmony_ci}
15401cb0ef41Sopenharmony_ci
15411cb0ef41Sopenharmony_ciBackgroundCompileTask::BackgroundCompileTask(
15421cb0ef41Sopenharmony_ci    Isolate* isolate, Handle<SharedFunctionInfo> shared_info,
15431cb0ef41Sopenharmony_ci    std::unique_ptr<Utf16CharacterStream> character_stream,
15441cb0ef41Sopenharmony_ci    WorkerThreadRuntimeCallStats* worker_thread_runtime_stats,
15451cb0ef41Sopenharmony_ci    TimedHistogram* timer, int max_stack_size)
15461cb0ef41Sopenharmony_ci    : isolate_for_local_isolate_(isolate),
15471cb0ef41Sopenharmony_ci      // TODO(leszeks): Create this from parent compile flags, to avoid
15481cb0ef41Sopenharmony_ci      // accessing the Isolate.
15491cb0ef41Sopenharmony_ci      flags_(
15501cb0ef41Sopenharmony_ci          UnoptimizedCompileFlags::ForFunctionCompile(isolate, *shared_info)),
15511cb0ef41Sopenharmony_ci      character_stream_(std::move(character_stream)),
15521cb0ef41Sopenharmony_ci      stack_size_(max_stack_size),
15531cb0ef41Sopenharmony_ci      worker_thread_runtime_call_stats_(worker_thread_runtime_stats),
15541cb0ef41Sopenharmony_ci      timer_(timer),
15551cb0ef41Sopenharmony_ci      input_shared_info_(shared_info),
15561cb0ef41Sopenharmony_ci      start_position_(shared_info->StartPosition()),
15571cb0ef41Sopenharmony_ci      end_position_(shared_info->EndPosition()),
15581cb0ef41Sopenharmony_ci      function_literal_id_(shared_info->function_literal_id()) {
15591cb0ef41Sopenharmony_ci  DCHECK(!shared_info->is_toplevel());
15601cb0ef41Sopenharmony_ci
15611cb0ef41Sopenharmony_ci  character_stream_->Seek(start_position_);
15621cb0ef41Sopenharmony_ci
15631cb0ef41Sopenharmony_ci  // Get the script out of the outer ParseInfo and turn it into a persistent
15641cb0ef41Sopenharmony_ci  // handle we can transfer to the background thread.
15651cb0ef41Sopenharmony_ci  persistent_handles_ = std::make_unique<PersistentHandles>(isolate);
15661cb0ef41Sopenharmony_ci  input_shared_info_ = persistent_handles_->NewHandle(shared_info);
15671cb0ef41Sopenharmony_ci}
15681cb0ef41Sopenharmony_ci
15691cb0ef41Sopenharmony_ciBackgroundCompileTask::~BackgroundCompileTask() = default;
15701cb0ef41Sopenharmony_ci
15711cb0ef41Sopenharmony_cinamespace {
15721cb0ef41Sopenharmony_ci
15731cb0ef41Sopenharmony_civoid SetScriptFieldsFromDetails(Isolate* isolate, Script script,
15741cb0ef41Sopenharmony_ci                                ScriptDetails script_details,
15751cb0ef41Sopenharmony_ci                                DisallowGarbageCollection* no_gc) {
15761cb0ef41Sopenharmony_ci  Handle<Object> script_name;
15771cb0ef41Sopenharmony_ci  if (script_details.name_obj.ToHandle(&script_name)) {
15781cb0ef41Sopenharmony_ci    script.set_name(*script_name);
15791cb0ef41Sopenharmony_ci    script.set_line_offset(script_details.line_offset);
15801cb0ef41Sopenharmony_ci    script.set_column_offset(script_details.column_offset);
15811cb0ef41Sopenharmony_ci  }
15821cb0ef41Sopenharmony_ci  // The API can provide a source map URL, but a source map URL could also have
15831cb0ef41Sopenharmony_ci  // been inferred by the parser from a magic comment. The latter takes
15841cb0ef41Sopenharmony_ci  // preference over the former, so we don't want to override the source mapping
15851cb0ef41Sopenharmony_ci  // URL if it already exists.
15861cb0ef41Sopenharmony_ci  Handle<Object> source_map_url;
15871cb0ef41Sopenharmony_ci  if (script_details.source_map_url.ToHandle(&source_map_url) &&
15881cb0ef41Sopenharmony_ci      script.source_mapping_url(isolate).IsUndefined(isolate)) {
15891cb0ef41Sopenharmony_ci    script.set_source_mapping_url(*source_map_url);
15901cb0ef41Sopenharmony_ci  }
15911cb0ef41Sopenharmony_ci  Handle<Object> host_defined_options;
15921cb0ef41Sopenharmony_ci  if (script_details.host_defined_options.ToHandle(&host_defined_options)) {
15931cb0ef41Sopenharmony_ci    // TODO(cbruni, chromium:1244145): Remove once migrated to the context.
15941cb0ef41Sopenharmony_ci    if (host_defined_options->IsFixedArray()) {
15951cb0ef41Sopenharmony_ci      script.set_host_defined_options(FixedArray::cast(*host_defined_options));
15961cb0ef41Sopenharmony_ci    }
15971cb0ef41Sopenharmony_ci  }
15981cb0ef41Sopenharmony_ci}
15991cb0ef41Sopenharmony_ci
16001cb0ef41Sopenharmony_ci}  // namespace
16011cb0ef41Sopenharmony_ci
16021cb0ef41Sopenharmony_civoid BackgroundCompileTask::Run() {
16031cb0ef41Sopenharmony_ci  DCHECK_NE(ThreadId::Current(), isolate_for_local_isolate_->thread_id());
16041cb0ef41Sopenharmony_ci  LocalIsolate isolate(isolate_for_local_isolate_, ThreadKind::kBackground);
16051cb0ef41Sopenharmony_ci  UnparkedScope unparked_scope(&isolate);
16061cb0ef41Sopenharmony_ci  LocalHandleScope handle_scope(&isolate);
16071cb0ef41Sopenharmony_ci
16081cb0ef41Sopenharmony_ci  ReusableUnoptimizedCompileState reusable_state(&isolate);
16091cb0ef41Sopenharmony_ci
16101cb0ef41Sopenharmony_ci  Run(&isolate, &reusable_state);
16111cb0ef41Sopenharmony_ci}
16121cb0ef41Sopenharmony_ci
16131cb0ef41Sopenharmony_civoid BackgroundCompileTask::RunOnMainThread(Isolate* isolate) {
16141cb0ef41Sopenharmony_ci  LocalHandleScope handle_scope(isolate->main_thread_local_isolate());
16151cb0ef41Sopenharmony_ci  ReusableUnoptimizedCompileState reusable_state(isolate);
16161cb0ef41Sopenharmony_ci  Run(isolate->main_thread_local_isolate(), &reusable_state);
16171cb0ef41Sopenharmony_ci}
16181cb0ef41Sopenharmony_ci
16191cb0ef41Sopenharmony_civoid BackgroundCompileTask::Run(
16201cb0ef41Sopenharmony_ci    LocalIsolate* isolate, ReusableUnoptimizedCompileState* reusable_state) {
16211cb0ef41Sopenharmony_ci  TimedHistogramScope timer(timer_);
16221cb0ef41Sopenharmony_ci
16231cb0ef41Sopenharmony_ci  TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.compile"),
16241cb0ef41Sopenharmony_ci               "BackgroundCompileTask::Run");
16251cb0ef41Sopenharmony_ci  RCS_SCOPE(isolate, RuntimeCallCounterId::kCompileCompileTask,
16261cb0ef41Sopenharmony_ci            RuntimeCallStats::CounterMode::kThreadSpecific);
16271cb0ef41Sopenharmony_ci
16281cb0ef41Sopenharmony_ci  bool toplevel_script_compilation = flags_.is_toplevel();
16291cb0ef41Sopenharmony_ci
16301cb0ef41Sopenharmony_ci  ParseInfo info(isolate, flags_, &compile_state_, reusable_state,
16311cb0ef41Sopenharmony_ci                 GetCurrentStackPosition() - stack_size_ * KB);
16321cb0ef41Sopenharmony_ci  info.set_character_stream(std::move(character_stream_));
16331cb0ef41Sopenharmony_ci
16341cb0ef41Sopenharmony_ci  if (toplevel_script_compilation) {
16351cb0ef41Sopenharmony_ci    DCHECK_NULL(persistent_handles_);
16361cb0ef41Sopenharmony_ci    DCHECK(input_shared_info_.is_null());
16371cb0ef41Sopenharmony_ci
16381cb0ef41Sopenharmony_ci    // We don't have the script source, origin, or details yet, so use default
16391cb0ef41Sopenharmony_ci    // values for them. These will be fixed up during the main-thread merge.
16401cb0ef41Sopenharmony_ci    Handle<Script> script = info.CreateScript(
16411cb0ef41Sopenharmony_ci        isolate, isolate->factory()->empty_string(), kNullMaybeHandle,
16421cb0ef41Sopenharmony_ci        ScriptOriginOptions(false, false, false, info.flags().is_module()));
16431cb0ef41Sopenharmony_ci    script_ = isolate->heap()->NewPersistentHandle(script);
16441cb0ef41Sopenharmony_ci  } else {
16451cb0ef41Sopenharmony_ci    DCHECK_NOT_NULL(persistent_handles_);
16461cb0ef41Sopenharmony_ci    isolate->heap()->AttachPersistentHandles(std::move(persistent_handles_));
16471cb0ef41Sopenharmony_ci    Handle<SharedFunctionInfo> shared_info =
16481cb0ef41Sopenharmony_ci        input_shared_info_.ToHandleChecked();
16491cb0ef41Sopenharmony_ci    script_ = isolate->heap()->NewPersistentHandle(
16501cb0ef41Sopenharmony_ci        Script::cast(shared_info->script()));
16511cb0ef41Sopenharmony_ci    info.CheckFlagsForFunctionFromScript(*script_);
16521cb0ef41Sopenharmony_ci
16531cb0ef41Sopenharmony_ci    {
16541cb0ef41Sopenharmony_ci      SharedStringAccessGuardIfNeeded access_guard(isolate);
16551cb0ef41Sopenharmony_ci      info.set_function_name(info.ast_value_factory()->GetString(
16561cb0ef41Sopenharmony_ci          shared_info->Name(), access_guard));
16571cb0ef41Sopenharmony_ci    }
16581cb0ef41Sopenharmony_ci
16591cb0ef41Sopenharmony_ci    // Get preparsed scope data from the function literal.
16601cb0ef41Sopenharmony_ci    if (shared_info->HasUncompiledDataWithPreparseData()) {
16611cb0ef41Sopenharmony_ci      info.set_consumed_preparse_data(ConsumedPreparseData::For(
16621cb0ef41Sopenharmony_ci          isolate, handle(shared_info->uncompiled_data_with_preparse_data()
16631cb0ef41Sopenharmony_ci                              .preparse_data(isolate),
16641cb0ef41Sopenharmony_ci                          isolate)));
16651cb0ef41Sopenharmony_ci    }
16661cb0ef41Sopenharmony_ci  }
16671cb0ef41Sopenharmony_ci
16681cb0ef41Sopenharmony_ci  // Update the character stream's runtime call stats.
16691cb0ef41Sopenharmony_ci  info.character_stream()->set_runtime_call_stats(info.runtime_call_stats());
16701cb0ef41Sopenharmony_ci
16711cb0ef41Sopenharmony_ci  // Parser needs to stay alive for finalizing the parsing on the main
16721cb0ef41Sopenharmony_ci  // thread.
16731cb0ef41Sopenharmony_ci  Parser parser(isolate, &info, script_);
16741cb0ef41Sopenharmony_ci  if (flags().is_toplevel()) {
16751cb0ef41Sopenharmony_ci    parser.InitializeEmptyScopeChain(&info);
16761cb0ef41Sopenharmony_ci  } else {
16771cb0ef41Sopenharmony_ci    // TODO(leszeks): Consider keeping Scope zones alive between compile tasks
16781cb0ef41Sopenharmony_ci    // and passing the Scope for the FunctionLiteral through here directly
16791cb0ef41Sopenharmony_ci    // without copying/deserializing.
16801cb0ef41Sopenharmony_ci    Handle<SharedFunctionInfo> shared_info =
16811cb0ef41Sopenharmony_ci        input_shared_info_.ToHandleChecked();
16821cb0ef41Sopenharmony_ci    MaybeHandle<ScopeInfo> maybe_outer_scope_info;
16831cb0ef41Sopenharmony_ci    if (shared_info->HasOuterScopeInfo()) {
16841cb0ef41Sopenharmony_ci      maybe_outer_scope_info =
16851cb0ef41Sopenharmony_ci          handle(shared_info->GetOuterScopeInfo(), isolate);
16861cb0ef41Sopenharmony_ci    }
16871cb0ef41Sopenharmony_ci    parser.DeserializeScopeChain(
16881cb0ef41Sopenharmony_ci        isolate, &info, maybe_outer_scope_info,
16891cb0ef41Sopenharmony_ci        Scope::DeserializationMode::kIncludingVariables);
16901cb0ef41Sopenharmony_ci  }
16911cb0ef41Sopenharmony_ci
16921cb0ef41Sopenharmony_ci  parser.ParseOnBackground(isolate, &info, start_position_, end_position_,
16931cb0ef41Sopenharmony_ci                           function_literal_id_);
16941cb0ef41Sopenharmony_ci  parser.UpdateStatistics(script_, &use_counts_, &total_preparse_skipped_);
16951cb0ef41Sopenharmony_ci
16961cb0ef41Sopenharmony_ci  TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.compile"),
16971cb0ef41Sopenharmony_ci               "V8.CompileCodeBackground");
16981cb0ef41Sopenharmony_ci  RCS_SCOPE(isolate, RuntimeCallCounterIdForCompile(&info),
16991cb0ef41Sopenharmony_ci            RuntimeCallStats::CounterMode::kThreadSpecific);
17001cb0ef41Sopenharmony_ci
17011cb0ef41Sopenharmony_ci  MaybeHandle<SharedFunctionInfo> maybe_result;
17021cb0ef41Sopenharmony_ci  if (info.literal() != nullptr) {
17031cb0ef41Sopenharmony_ci    Handle<SharedFunctionInfo> shared_info;
17041cb0ef41Sopenharmony_ci    if (toplevel_script_compilation) {
17051cb0ef41Sopenharmony_ci      shared_info = CreateTopLevelSharedFunctionInfo(&info, script_, isolate);
17061cb0ef41Sopenharmony_ci    } else {
17071cb0ef41Sopenharmony_ci      // Clone into a placeholder SFI for storing the results.
17081cb0ef41Sopenharmony_ci      shared_info = isolate->factory()->CloneSharedFunctionInfo(
17091cb0ef41Sopenharmony_ci          input_shared_info_.ToHandleChecked());
17101cb0ef41Sopenharmony_ci    }
17111cb0ef41Sopenharmony_ci
17121cb0ef41Sopenharmony_ci    if (IterativelyExecuteAndFinalizeUnoptimizedCompilationJobs(
17131cb0ef41Sopenharmony_ci            isolate, shared_info, script_, &info, reusable_state->allocator(),
17141cb0ef41Sopenharmony_ci            &is_compiled_scope_, &finalize_unoptimized_compilation_data_,
17151cb0ef41Sopenharmony_ci            &jobs_to_retry_finalization_on_main_thread_)) {
17161cb0ef41Sopenharmony_ci      maybe_result = shared_info;
17171cb0ef41Sopenharmony_ci    }
17181cb0ef41Sopenharmony_ci  }
17191cb0ef41Sopenharmony_ci
17201cb0ef41Sopenharmony_ci  if (maybe_result.is_null()) {
17211cb0ef41Sopenharmony_ci    PreparePendingException(isolate, &info);
17221cb0ef41Sopenharmony_ci  }
17231cb0ef41Sopenharmony_ci
17241cb0ef41Sopenharmony_ci  outer_function_sfi_ = isolate->heap()->NewPersistentMaybeHandle(maybe_result);
17251cb0ef41Sopenharmony_ci  DCHECK(isolate->heap()->ContainsPersistentHandle(script_.location()));
17261cb0ef41Sopenharmony_ci  persistent_handles_ = isolate->heap()->DetachPersistentHandles();
17271cb0ef41Sopenharmony_ci}
17281cb0ef41Sopenharmony_ci
17291cb0ef41Sopenharmony_ciMaybeHandle<SharedFunctionInfo> BackgroundCompileTask::FinalizeScript(
17301cb0ef41Sopenharmony_ci    Isolate* isolate, Handle<String> source,
17311cb0ef41Sopenharmony_ci    const ScriptDetails& script_details) {
17321cb0ef41Sopenharmony_ci  ScriptOriginOptions origin_options = script_details.origin_options;
17331cb0ef41Sopenharmony_ci
17341cb0ef41Sopenharmony_ci  DCHECK(flags_.is_toplevel());
17351cb0ef41Sopenharmony_ci  DCHECK_EQ(flags_.is_module(), origin_options.IsModule());
17361cb0ef41Sopenharmony_ci
17371cb0ef41Sopenharmony_ci  MaybeHandle<SharedFunctionInfo> maybe_result;
17381cb0ef41Sopenharmony_ci
17391cb0ef41Sopenharmony_ci  // We might not have been able to finalize all jobs on the background
17401cb0ef41Sopenharmony_ci  // thread (e.g. asm.js jobs), so finalize those deferred jobs now.
17411cb0ef41Sopenharmony_ci  if (FinalizeDeferredUnoptimizedCompilationJobs(
17421cb0ef41Sopenharmony_ci          isolate, script_, &jobs_to_retry_finalization_on_main_thread_,
17431cb0ef41Sopenharmony_ci          compile_state_.pending_error_handler(),
17441cb0ef41Sopenharmony_ci          &finalize_unoptimized_compilation_data_)) {
17451cb0ef41Sopenharmony_ci    maybe_result = outer_function_sfi_;
17461cb0ef41Sopenharmony_ci  }
17471cb0ef41Sopenharmony_ci
17481cb0ef41Sopenharmony_ci  script_->set_source(*source);
17491cb0ef41Sopenharmony_ci  script_->set_origin_options(origin_options);
17501cb0ef41Sopenharmony_ci
17511cb0ef41Sopenharmony_ci  // The one post-hoc fix-up: Add the script to the script list.
17521cb0ef41Sopenharmony_ci  Handle<WeakArrayList> scripts = isolate->factory()->script_list();
17531cb0ef41Sopenharmony_ci  scripts =
17541cb0ef41Sopenharmony_ci      WeakArrayList::Append(isolate, scripts, MaybeObjectHandle::Weak(script_));
17551cb0ef41Sopenharmony_ci  isolate->heap()->SetRootScriptList(*scripts);
17561cb0ef41Sopenharmony_ci
17571cb0ef41Sopenharmony_ci  // Set the script fields after finalization, to keep this path the same
17581cb0ef41Sopenharmony_ci  // between main-thread and off-thread finalization.
17591cb0ef41Sopenharmony_ci  {
17601cb0ef41Sopenharmony_ci    DisallowGarbageCollection no_gc;
17611cb0ef41Sopenharmony_ci    SetScriptFieldsFromDetails(isolate, *script_, script_details, &no_gc);
17621cb0ef41Sopenharmony_ci    LOG(isolate, ScriptDetails(*script_));
17631cb0ef41Sopenharmony_ci  }
17641cb0ef41Sopenharmony_ci
17651cb0ef41Sopenharmony_ci  ReportStatistics(isolate);
17661cb0ef41Sopenharmony_ci
17671cb0ef41Sopenharmony_ci  Handle<SharedFunctionInfo> result;
17681cb0ef41Sopenharmony_ci  if (!maybe_result.ToHandle(&result)) {
17691cb0ef41Sopenharmony_ci    FailWithPreparedPendingException(isolate, script_,
17701cb0ef41Sopenharmony_ci                                     compile_state_.pending_error_handler());
17711cb0ef41Sopenharmony_ci    return kNullMaybeHandle;
17721cb0ef41Sopenharmony_ci  }
17731cb0ef41Sopenharmony_ci
17741cb0ef41Sopenharmony_ci  FinalizeUnoptimizedScriptCompilation(isolate, script_, flags_,
17751cb0ef41Sopenharmony_ci                                       &compile_state_,
17761cb0ef41Sopenharmony_ci                                       finalize_unoptimized_compilation_data_);
17771cb0ef41Sopenharmony_ci
17781cb0ef41Sopenharmony_ci  return handle(*result, isolate);
17791cb0ef41Sopenharmony_ci}
17801cb0ef41Sopenharmony_ci
17811cb0ef41Sopenharmony_cibool BackgroundCompileTask::FinalizeFunction(
17821cb0ef41Sopenharmony_ci    Isolate* isolate, Compiler::ClearExceptionFlag flag) {
17831cb0ef41Sopenharmony_ci  DCHECK(!flags_.is_toplevel());
17841cb0ef41Sopenharmony_ci
17851cb0ef41Sopenharmony_ci  MaybeHandle<SharedFunctionInfo> maybe_result;
17861cb0ef41Sopenharmony_ci  Handle<SharedFunctionInfo> input_shared_info =
17871cb0ef41Sopenharmony_ci      input_shared_info_.ToHandleChecked();
17881cb0ef41Sopenharmony_ci
17891cb0ef41Sopenharmony_ci  // The UncompiledData on the input SharedFunctionInfo will have a pointer to
17901cb0ef41Sopenharmony_ci  // the LazyCompileDispatcher Job that launched this task, which will now be
17911cb0ef41Sopenharmony_ci  // considered complete, so clear that regardless of whether the finalize
17921cb0ef41Sopenharmony_ci  // succeeds or not.
17931cb0ef41Sopenharmony_ci  input_shared_info->ClearUncompiledDataJobPointer();
17941cb0ef41Sopenharmony_ci
17951cb0ef41Sopenharmony_ci  // We might not have been able to finalize all jobs on the background
17961cb0ef41Sopenharmony_ci  // thread (e.g. asm.js jobs), so finalize those deferred jobs now.
17971cb0ef41Sopenharmony_ci  if (FinalizeDeferredUnoptimizedCompilationJobs(
17981cb0ef41Sopenharmony_ci          isolate, script_, &jobs_to_retry_finalization_on_main_thread_,
17991cb0ef41Sopenharmony_ci          compile_state_.pending_error_handler(),
18001cb0ef41Sopenharmony_ci          &finalize_unoptimized_compilation_data_)) {
18011cb0ef41Sopenharmony_ci    maybe_result = outer_function_sfi_;
18021cb0ef41Sopenharmony_ci  }
18031cb0ef41Sopenharmony_ci
18041cb0ef41Sopenharmony_ci  ReportStatistics(isolate);
18051cb0ef41Sopenharmony_ci
18061cb0ef41Sopenharmony_ci  Handle<SharedFunctionInfo> result;
18071cb0ef41Sopenharmony_ci  if (!maybe_result.ToHandle(&result)) {
18081cb0ef41Sopenharmony_ci    FailWithPreparedPendingException(
18091cb0ef41Sopenharmony_ci        isolate, script_, compile_state_.pending_error_handler(), flag);
18101cb0ef41Sopenharmony_ci    return false;
18111cb0ef41Sopenharmony_ci  }
18121cb0ef41Sopenharmony_ci
18131cb0ef41Sopenharmony_ci  FinalizeUnoptimizedCompilation(isolate, script_, flags_, &compile_state_,
18141cb0ef41Sopenharmony_ci                                 finalize_unoptimized_compilation_data_);
18151cb0ef41Sopenharmony_ci
18161cb0ef41Sopenharmony_ci  // Move the compiled data from the placeholder SFI back to the real SFI.
18171cb0ef41Sopenharmony_ci  input_shared_info->CopyFrom(*result);
18181cb0ef41Sopenharmony_ci
18191cb0ef41Sopenharmony_ci  return true;
18201cb0ef41Sopenharmony_ci}
18211cb0ef41Sopenharmony_ci
18221cb0ef41Sopenharmony_civoid BackgroundCompileTask::AbortFunction() {
18231cb0ef41Sopenharmony_ci  // The UncompiledData on the input SharedFunctionInfo will have a pointer to
18241cb0ef41Sopenharmony_ci  // the LazyCompileDispatcher Job that launched this task, which is about to be
18251cb0ef41Sopenharmony_ci  // deleted, so clear that to avoid the SharedFunctionInfo from pointing to
18261cb0ef41Sopenharmony_ci  // deallocated memory.
18271cb0ef41Sopenharmony_ci  input_shared_info_.ToHandleChecked()->ClearUncompiledDataJobPointer();
18281cb0ef41Sopenharmony_ci}
18291cb0ef41Sopenharmony_ci
18301cb0ef41Sopenharmony_civoid BackgroundCompileTask::ReportStatistics(Isolate* isolate) {
18311cb0ef41Sopenharmony_ci  // Update use-counts.
18321cb0ef41Sopenharmony_ci  for (auto feature : use_counts_) {
18331cb0ef41Sopenharmony_ci    isolate->CountUsage(feature);
18341cb0ef41Sopenharmony_ci  }
18351cb0ef41Sopenharmony_ci  if (total_preparse_skipped_ > 0) {
18361cb0ef41Sopenharmony_ci    isolate->counters()->total_preparse_skipped()->Increment(
18371cb0ef41Sopenharmony_ci        total_preparse_skipped_);
18381cb0ef41Sopenharmony_ci  }
18391cb0ef41Sopenharmony_ci}
18401cb0ef41Sopenharmony_ci
18411cb0ef41Sopenharmony_ciBackgroundDeserializeTask::BackgroundDeserializeTask(
18421cb0ef41Sopenharmony_ci    Isolate* isolate, std::unique_ptr<ScriptCompiler::CachedData> cached_data)
18431cb0ef41Sopenharmony_ci    : isolate_for_local_isolate_(isolate),
18441cb0ef41Sopenharmony_ci      cached_data_(cached_data->data, cached_data->length) {
18451cb0ef41Sopenharmony_ci  // If the passed in cached data has ownership of the buffer, move it to the
18461cb0ef41Sopenharmony_ci  // task.
18471cb0ef41Sopenharmony_ci  if (cached_data->buffer_policy == ScriptCompiler::CachedData::BufferOwned &&
18481cb0ef41Sopenharmony_ci      !cached_data_.HasDataOwnership()) {
18491cb0ef41Sopenharmony_ci    cached_data->buffer_policy = ScriptCompiler::CachedData::BufferNotOwned;
18501cb0ef41Sopenharmony_ci    cached_data_.AcquireDataOwnership();
18511cb0ef41Sopenharmony_ci  }
18521cb0ef41Sopenharmony_ci}
18531cb0ef41Sopenharmony_ci
18541cb0ef41Sopenharmony_civoid BackgroundDeserializeTask::Run() {
18551cb0ef41Sopenharmony_ci  LocalIsolate isolate(isolate_for_local_isolate_, ThreadKind::kBackground);
18561cb0ef41Sopenharmony_ci  UnparkedScope unparked_scope(&isolate);
18571cb0ef41Sopenharmony_ci  LocalHandleScope handle_scope(&isolate);
18581cb0ef41Sopenharmony_ci
18591cb0ef41Sopenharmony_ci  Handle<SharedFunctionInfo> inner_result;
18601cb0ef41Sopenharmony_ci  off_thread_data_ =
18611cb0ef41Sopenharmony_ci      CodeSerializer::StartDeserializeOffThread(&isolate, &cached_data_);
18621cb0ef41Sopenharmony_ci}
18631cb0ef41Sopenharmony_ci
18641cb0ef41Sopenharmony_ciMaybeHandle<SharedFunctionInfo> BackgroundDeserializeTask::Finish(
18651cb0ef41Sopenharmony_ci    Isolate* isolate, Handle<String> source,
18661cb0ef41Sopenharmony_ci    ScriptOriginOptions origin_options) {
18671cb0ef41Sopenharmony_ci  return CodeSerializer::FinishOffThreadDeserialize(
18681cb0ef41Sopenharmony_ci      isolate, std::move(off_thread_data_), &cached_data_, source,
18691cb0ef41Sopenharmony_ci      origin_options);
18701cb0ef41Sopenharmony_ci}
18711cb0ef41Sopenharmony_ci
18721cb0ef41Sopenharmony_ci// ----------------------------------------------------------------------------
18731cb0ef41Sopenharmony_ci// Implementation of Compiler
18741cb0ef41Sopenharmony_ci
18751cb0ef41Sopenharmony_ci// static
18761cb0ef41Sopenharmony_cibool Compiler::CollectSourcePositions(Isolate* isolate,
18771cb0ef41Sopenharmony_ci                                      Handle<SharedFunctionInfo> shared_info) {
18781cb0ef41Sopenharmony_ci  DCHECK(shared_info->is_compiled());
18791cb0ef41Sopenharmony_ci  DCHECK(shared_info->HasBytecodeArray());
18801cb0ef41Sopenharmony_ci  DCHECK(!shared_info->GetBytecodeArray(isolate).HasSourcePositionTable());
18811cb0ef41Sopenharmony_ci
18821cb0ef41Sopenharmony_ci  // Source position collection should be context independent.
18831cb0ef41Sopenharmony_ci  NullContextScope null_context_scope(isolate);
18841cb0ef41Sopenharmony_ci
18851cb0ef41Sopenharmony_ci  // Collecting source positions requires allocating a new source position
18861cb0ef41Sopenharmony_ci  // table.
18871cb0ef41Sopenharmony_ci  DCHECK(AllowHeapAllocation::IsAllowed());
18881cb0ef41Sopenharmony_ci
18891cb0ef41Sopenharmony_ci  Handle<BytecodeArray> bytecode =
18901cb0ef41Sopenharmony_ci      handle(shared_info->GetBytecodeArray(isolate), isolate);
18911cb0ef41Sopenharmony_ci
18921cb0ef41Sopenharmony_ci  // TODO(v8:8510): Push the CLEAR_EXCEPTION flag or something like it down into
18931cb0ef41Sopenharmony_ci  // the parser so it aborts without setting a pending exception, which then
18941cb0ef41Sopenharmony_ci  // gets thrown. This would avoid the situation where potentially we'd reparse
18951cb0ef41Sopenharmony_ci  // several times (running out of stack each time) before hitting this limit.
18961cb0ef41Sopenharmony_ci  if (GetCurrentStackPosition() < isolate->stack_guard()->real_climit()) {
18971cb0ef41Sopenharmony_ci    // Stack is already exhausted.
18981cb0ef41Sopenharmony_ci    bytecode->SetSourcePositionsFailedToCollect();
18991cb0ef41Sopenharmony_ci    return false;
19001cb0ef41Sopenharmony_ci  }
19011cb0ef41Sopenharmony_ci
19021cb0ef41Sopenharmony_ci  // Unfinalized scripts don't yet have the proper source string attached and
19031cb0ef41Sopenharmony_ci  // thus can't be reparsed.
19041cb0ef41Sopenharmony_ci  if (Script::cast(shared_info->script()).IsMaybeUnfinalized(isolate)) {
19051cb0ef41Sopenharmony_ci    bytecode->SetSourcePositionsFailedToCollect();
19061cb0ef41Sopenharmony_ci    return false;
19071cb0ef41Sopenharmony_ci  }
19081cb0ef41Sopenharmony_ci
19091cb0ef41Sopenharmony_ci  DCHECK(AllowCompilation::IsAllowed(isolate));
19101cb0ef41Sopenharmony_ci  DCHECK_EQ(ThreadId::Current(), isolate->thread_id());
19111cb0ef41Sopenharmony_ci  DCHECK(!isolate->has_pending_exception());
19121cb0ef41Sopenharmony_ci  VMState<BYTECODE_COMPILER> state(isolate);
19131cb0ef41Sopenharmony_ci  PostponeInterruptsScope postpone(isolate);
19141cb0ef41Sopenharmony_ci  RCS_SCOPE(isolate, RuntimeCallCounterId::kCompileCollectSourcePositions);
19151cb0ef41Sopenharmony_ci  TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.compile"),
19161cb0ef41Sopenharmony_ci               "V8.CollectSourcePositions");
19171cb0ef41Sopenharmony_ci  NestedTimedHistogramScope timer(
19181cb0ef41Sopenharmony_ci      isolate->counters()->collect_source_positions());
19191cb0ef41Sopenharmony_ci
19201cb0ef41Sopenharmony_ci  // Set up parse info.
19211cb0ef41Sopenharmony_ci  UnoptimizedCompileFlags flags =
19221cb0ef41Sopenharmony_ci      UnoptimizedCompileFlags::ForFunctionCompile(isolate, *shared_info);
19231cb0ef41Sopenharmony_ci  flags.set_collect_source_positions(true);
19241cb0ef41Sopenharmony_ci  // Prevent parallel tasks from being spawned by this job.
19251cb0ef41Sopenharmony_ci  flags.set_post_parallel_compile_tasks_for_eager_toplevel(false);
19261cb0ef41Sopenharmony_ci  flags.set_post_parallel_compile_tasks_for_lazy(false);
19271cb0ef41Sopenharmony_ci
19281cb0ef41Sopenharmony_ci  UnoptimizedCompileState compile_state;
19291cb0ef41Sopenharmony_ci  ReusableUnoptimizedCompileState reusable_state(isolate);
19301cb0ef41Sopenharmony_ci  ParseInfo parse_info(isolate, flags, &compile_state, &reusable_state);
19311cb0ef41Sopenharmony_ci
19321cb0ef41Sopenharmony_ci  // Parse and update ParseInfo with the results. Don't update parsing
19331cb0ef41Sopenharmony_ci  // statistics since we've already parsed the code before.
19341cb0ef41Sopenharmony_ci  if (!parsing::ParseAny(&parse_info, shared_info, isolate,
19351cb0ef41Sopenharmony_ci                         parsing::ReportStatisticsMode::kNo)) {
19361cb0ef41Sopenharmony_ci    // Parsing failed probably as a result of stack exhaustion.
19371cb0ef41Sopenharmony_ci    bytecode->SetSourcePositionsFailedToCollect();
19381cb0ef41Sopenharmony_ci    return FailAndClearPendingException(isolate);
19391cb0ef41Sopenharmony_ci  }
19401cb0ef41Sopenharmony_ci
19411cb0ef41Sopenharmony_ci  // Character stream shouldn't be used again.
19421cb0ef41Sopenharmony_ci  parse_info.ResetCharacterStream();
19431cb0ef41Sopenharmony_ci
19441cb0ef41Sopenharmony_ci  // Generate the unoptimized bytecode.
19451cb0ef41Sopenharmony_ci  // TODO(v8:8510): Consider forcing preparsing of inner functions to avoid
19461cb0ef41Sopenharmony_ci  // wasting time fully parsing them when they won't ever be used.
19471cb0ef41Sopenharmony_ci  std::unique_ptr<UnoptimizedCompilationJob> job;
19481cb0ef41Sopenharmony_ci  {
19491cb0ef41Sopenharmony_ci    job = interpreter::Interpreter::NewSourcePositionCollectionJob(
19501cb0ef41Sopenharmony_ci        &parse_info, parse_info.literal(), bytecode, isolate->allocator(),
19511cb0ef41Sopenharmony_ci        isolate->main_thread_local_isolate());
19521cb0ef41Sopenharmony_ci
19531cb0ef41Sopenharmony_ci    if (!job || job->ExecuteJob() != CompilationJob::SUCCEEDED ||
19541cb0ef41Sopenharmony_ci        job->FinalizeJob(shared_info, isolate) != CompilationJob::SUCCEEDED) {
19551cb0ef41Sopenharmony_ci      // Recompiling failed probably as a result of stack exhaustion.
19561cb0ef41Sopenharmony_ci      bytecode->SetSourcePositionsFailedToCollect();
19571cb0ef41Sopenharmony_ci      return FailAndClearPendingException(isolate);
19581cb0ef41Sopenharmony_ci    }
19591cb0ef41Sopenharmony_ci  }
19601cb0ef41Sopenharmony_ci
19611cb0ef41Sopenharmony_ci  DCHECK(job->compilation_info()->flags().collect_source_positions());
19621cb0ef41Sopenharmony_ci
19631cb0ef41Sopenharmony_ci  // If debugging, make sure that instrumented bytecode has the source position
19641cb0ef41Sopenharmony_ci  // table set on it as well.
19651cb0ef41Sopenharmony_ci  if (shared_info->HasDebugInfo() &&
19661cb0ef41Sopenharmony_ci      shared_info->GetDebugInfo().HasInstrumentedBytecodeArray()) {
19671cb0ef41Sopenharmony_ci    ByteArray source_position_table =
19681cb0ef41Sopenharmony_ci        job->compilation_info()->bytecode_array()->SourcePositionTable();
19691cb0ef41Sopenharmony_ci    shared_info->GetActiveBytecodeArray().set_source_position_table(
19701cb0ef41Sopenharmony_ci        source_position_table, kReleaseStore);
19711cb0ef41Sopenharmony_ci  }
19721cb0ef41Sopenharmony_ci
19731cb0ef41Sopenharmony_ci  DCHECK(!isolate->has_pending_exception());
19741cb0ef41Sopenharmony_ci  DCHECK(shared_info->is_compiled_scope(isolate).is_compiled());
19751cb0ef41Sopenharmony_ci  return true;
19761cb0ef41Sopenharmony_ci}
19771cb0ef41Sopenharmony_ci
19781cb0ef41Sopenharmony_ci// static
19791cb0ef41Sopenharmony_cibool Compiler::Compile(Isolate* isolate, Handle<SharedFunctionInfo> shared_info,
19801cb0ef41Sopenharmony_ci                       ClearExceptionFlag flag,
19811cb0ef41Sopenharmony_ci                       IsCompiledScope* is_compiled_scope,
19821cb0ef41Sopenharmony_ci                       CreateSourcePositions create_source_positions_flag) {
19831cb0ef41Sopenharmony_ci  // We should never reach here if the function is already compiled.
19841cb0ef41Sopenharmony_ci  DCHECK(!shared_info->is_compiled());
19851cb0ef41Sopenharmony_ci  DCHECK(!is_compiled_scope->is_compiled());
19861cb0ef41Sopenharmony_ci  DCHECK(AllowCompilation::IsAllowed(isolate));
19871cb0ef41Sopenharmony_ci  DCHECK_EQ(ThreadId::Current(), isolate->thread_id());
19881cb0ef41Sopenharmony_ci  DCHECK(!isolate->has_pending_exception());
19891cb0ef41Sopenharmony_ci  DCHECK(!shared_info->HasBytecodeArray());
19901cb0ef41Sopenharmony_ci
19911cb0ef41Sopenharmony_ci  VMState<BYTECODE_COMPILER> state(isolate);
19921cb0ef41Sopenharmony_ci  PostponeInterruptsScope postpone(isolate);
19931cb0ef41Sopenharmony_ci  TimerEventScope<TimerEventCompileCode> compile_timer(isolate);
19941cb0ef41Sopenharmony_ci  RCS_SCOPE(isolate, RuntimeCallCounterId::kCompileFunction);
19951cb0ef41Sopenharmony_ci  TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.compile"), "V8.CompileCode");
19961cb0ef41Sopenharmony_ci  AggregatedHistogramTimerScope timer(isolate->counters()->compile_lazy());
19971cb0ef41Sopenharmony_ci
19981cb0ef41Sopenharmony_ci  Handle<Script> script(Script::cast(shared_info->script()), isolate);
19991cb0ef41Sopenharmony_ci
20001cb0ef41Sopenharmony_ci  // Set up parse info.
20011cb0ef41Sopenharmony_ci  UnoptimizedCompileFlags flags =
20021cb0ef41Sopenharmony_ci      UnoptimizedCompileFlags::ForFunctionCompile(isolate, *shared_info);
20031cb0ef41Sopenharmony_ci  if (create_source_positions_flag == CreateSourcePositions::kYes) {
20041cb0ef41Sopenharmony_ci    flags.set_collect_source_positions(true);
20051cb0ef41Sopenharmony_ci  }
20061cb0ef41Sopenharmony_ci
20071cb0ef41Sopenharmony_ci  UnoptimizedCompileState compile_state;
20081cb0ef41Sopenharmony_ci  ReusableUnoptimizedCompileState reusable_state(isolate);
20091cb0ef41Sopenharmony_ci  ParseInfo parse_info(isolate, flags, &compile_state, &reusable_state);
20101cb0ef41Sopenharmony_ci
20111cb0ef41Sopenharmony_ci  // Check if the compiler dispatcher has shared_info enqueued for compile.
20121cb0ef41Sopenharmony_ci  LazyCompileDispatcher* dispatcher = isolate->lazy_compile_dispatcher();
20131cb0ef41Sopenharmony_ci  if (dispatcher && dispatcher->IsEnqueued(shared_info)) {
20141cb0ef41Sopenharmony_ci    if (!dispatcher->FinishNow(shared_info)) {
20151cb0ef41Sopenharmony_ci      return FailWithPendingException(isolate, script, &parse_info, flag);
20161cb0ef41Sopenharmony_ci    }
20171cb0ef41Sopenharmony_ci    *is_compiled_scope = shared_info->is_compiled_scope(isolate);
20181cb0ef41Sopenharmony_ci    DCHECK(is_compiled_scope->is_compiled());
20191cb0ef41Sopenharmony_ci    return true;
20201cb0ef41Sopenharmony_ci  }
20211cb0ef41Sopenharmony_ci
20221cb0ef41Sopenharmony_ci  if (shared_info->HasUncompiledDataWithPreparseData()) {
20231cb0ef41Sopenharmony_ci    parse_info.set_consumed_preparse_data(ConsumedPreparseData::For(
20241cb0ef41Sopenharmony_ci        isolate,
20251cb0ef41Sopenharmony_ci        handle(
20261cb0ef41Sopenharmony_ci            shared_info->uncompiled_data_with_preparse_data().preparse_data(),
20271cb0ef41Sopenharmony_ci            isolate)));
20281cb0ef41Sopenharmony_ci  }
20291cb0ef41Sopenharmony_ci
20301cb0ef41Sopenharmony_ci  // Parse and update ParseInfo with the results.
20311cb0ef41Sopenharmony_ci  if (!parsing::ParseAny(&parse_info, shared_info, isolate,
20321cb0ef41Sopenharmony_ci                         parsing::ReportStatisticsMode::kYes)) {
20331cb0ef41Sopenharmony_ci    return FailWithPendingException(isolate, script, &parse_info, flag);
20341cb0ef41Sopenharmony_ci  }
20351cb0ef41Sopenharmony_ci
20361cb0ef41Sopenharmony_ci  // Generate the unoptimized bytecode or asm-js data.
20371cb0ef41Sopenharmony_ci  FinalizeUnoptimizedCompilationDataList
20381cb0ef41Sopenharmony_ci      finalize_unoptimized_compilation_data_list;
20391cb0ef41Sopenharmony_ci
20401cb0ef41Sopenharmony_ci  if (!IterativelyExecuteAndFinalizeUnoptimizedCompilationJobs(
20411cb0ef41Sopenharmony_ci          isolate, shared_info, script, &parse_info, isolate->allocator(),
20421cb0ef41Sopenharmony_ci          is_compiled_scope, &finalize_unoptimized_compilation_data_list,
20431cb0ef41Sopenharmony_ci          nullptr)) {
20441cb0ef41Sopenharmony_ci    return FailWithPendingException(isolate, script, &parse_info, flag);
20451cb0ef41Sopenharmony_ci  }
20461cb0ef41Sopenharmony_ci
20471cb0ef41Sopenharmony_ci  FinalizeUnoptimizedCompilation(isolate, script, flags, &compile_state,
20481cb0ef41Sopenharmony_ci                                 finalize_unoptimized_compilation_data_list);
20491cb0ef41Sopenharmony_ci
20501cb0ef41Sopenharmony_ci  if (FLAG_always_sparkplug) {
20511cb0ef41Sopenharmony_ci    CompileAllWithBaseline(isolate, finalize_unoptimized_compilation_data_list);
20521cb0ef41Sopenharmony_ci  }
20531cb0ef41Sopenharmony_ci
20541cb0ef41Sopenharmony_ci  DCHECK(!isolate->has_pending_exception());
20551cb0ef41Sopenharmony_ci  DCHECK(is_compiled_scope->is_compiled());
20561cb0ef41Sopenharmony_ci  return true;
20571cb0ef41Sopenharmony_ci}
20581cb0ef41Sopenharmony_ci
20591cb0ef41Sopenharmony_ci// static
20601cb0ef41Sopenharmony_cibool Compiler::Compile(Isolate* isolate, Handle<JSFunction> function,
20611cb0ef41Sopenharmony_ci                       ClearExceptionFlag flag,
20621cb0ef41Sopenharmony_ci                       IsCompiledScope* is_compiled_scope) {
20631cb0ef41Sopenharmony_ci  // We should never reach here if the function is already compiled or
20641cb0ef41Sopenharmony_ci  // optimized.
20651cb0ef41Sopenharmony_ci  DCHECK(!function->is_compiled());
20661cb0ef41Sopenharmony_ci  DCHECK(IsNone(function->tiering_state()));
20671cb0ef41Sopenharmony_ci  DCHECK(!function->HasAvailableOptimizedCode());
20681cb0ef41Sopenharmony_ci
20691cb0ef41Sopenharmony_ci  // Reset the JSFunction if we are recompiling due to the bytecode having been
20701cb0ef41Sopenharmony_ci  // flushed.
20711cb0ef41Sopenharmony_ci  function->ResetIfCodeFlushed();
20721cb0ef41Sopenharmony_ci
20731cb0ef41Sopenharmony_ci  Handle<SharedFunctionInfo> shared_info = handle(function->shared(), isolate);
20741cb0ef41Sopenharmony_ci
20751cb0ef41Sopenharmony_ci  // Ensure shared function info is compiled.
20761cb0ef41Sopenharmony_ci  *is_compiled_scope = shared_info->is_compiled_scope(isolate);
20771cb0ef41Sopenharmony_ci  if (!is_compiled_scope->is_compiled() &&
20781cb0ef41Sopenharmony_ci      !Compile(isolate, shared_info, flag, is_compiled_scope)) {
20791cb0ef41Sopenharmony_ci    return false;
20801cb0ef41Sopenharmony_ci  }
20811cb0ef41Sopenharmony_ci
20821cb0ef41Sopenharmony_ci  DCHECK(is_compiled_scope->is_compiled());
20831cb0ef41Sopenharmony_ci  Handle<CodeT> code = handle(shared_info->GetCode(), isolate);
20841cb0ef41Sopenharmony_ci
20851cb0ef41Sopenharmony_ci  // Initialize the feedback cell for this JSFunction and reset the interrupt
20861cb0ef41Sopenharmony_ci  // budget for feedback vector allocation even if there is a closure feedback
20871cb0ef41Sopenharmony_ci  // cell array. We are re-compiling when we have a closure feedback cell array
20881cb0ef41Sopenharmony_ci  // which means we are compiling after a bytecode flush.
20891cb0ef41Sopenharmony_ci  // TODO(verwaest/mythria): Investigate if allocating feedback vector
20901cb0ef41Sopenharmony_ci  // immediately after a flush would be better.
20911cb0ef41Sopenharmony_ci  JSFunction::InitializeFeedbackCell(function, is_compiled_scope, true);
20921cb0ef41Sopenharmony_ci
20931cb0ef41Sopenharmony_ci  // Optimize now if --always-opt is enabled.
20941cb0ef41Sopenharmony_ci#if V8_ENABLE_WEBASSEMBLY
20951cb0ef41Sopenharmony_ci  if (FLAG_always_opt && !function->shared().HasAsmWasmData()) {
20961cb0ef41Sopenharmony_ci#else
20971cb0ef41Sopenharmony_ci  if (FLAG_always_opt) {
20981cb0ef41Sopenharmony_ci#endif  // V8_ENABLE_WEBASSEMBLY
20991cb0ef41Sopenharmony_ci    CompilerTracer::TraceOptimizeForAlwaysOpt(isolate, function,
21001cb0ef41Sopenharmony_ci                                              CodeKindForTopTier());
21011cb0ef41Sopenharmony_ci
21021cb0ef41Sopenharmony_ci    const CodeKind code_kind = CodeKindForTopTier();
21031cb0ef41Sopenharmony_ci    const ConcurrencyMode concurrency_mode = ConcurrencyMode::kSynchronous;
21041cb0ef41Sopenharmony_ci
21051cb0ef41Sopenharmony_ci    if (FLAG_stress_concurrent_inlining &&
21061cb0ef41Sopenharmony_ci        isolate->concurrent_recompilation_enabled() &&
21071cb0ef41Sopenharmony_ci        isolate->node_observer() == nullptr) {
21081cb0ef41Sopenharmony_ci      SpawnDuplicateConcurrentJobForStressTesting(isolate, function,
21091cb0ef41Sopenharmony_ci                                                  concurrency_mode, code_kind);
21101cb0ef41Sopenharmony_ci    }
21111cb0ef41Sopenharmony_ci
21121cb0ef41Sopenharmony_ci    Handle<CodeT> maybe_code;
21131cb0ef41Sopenharmony_ci    if (GetOrCompileOptimized(isolate, function, concurrency_mode, code_kind)
21141cb0ef41Sopenharmony_ci            .ToHandle(&maybe_code)) {
21151cb0ef41Sopenharmony_ci      code = maybe_code;
21161cb0ef41Sopenharmony_ci    }
21171cb0ef41Sopenharmony_ci  }
21181cb0ef41Sopenharmony_ci
21191cb0ef41Sopenharmony_ci  // Install code on closure.
21201cb0ef41Sopenharmony_ci  function->set_code(*code, kReleaseStore);
21211cb0ef41Sopenharmony_ci
21221cb0ef41Sopenharmony_ci  // Install a feedback vector if necessary.
21231cb0ef41Sopenharmony_ci  if (code->kind() == CodeKind::BASELINE) {
21241cb0ef41Sopenharmony_ci    JSFunction::EnsureFeedbackVector(isolate, function, is_compiled_scope);
21251cb0ef41Sopenharmony_ci  }
21261cb0ef41Sopenharmony_ci
21271cb0ef41Sopenharmony_ci  // Check postconditions on success.
21281cb0ef41Sopenharmony_ci  DCHECK(!isolate->has_pending_exception());
21291cb0ef41Sopenharmony_ci  DCHECK(function->shared().is_compiled());
21301cb0ef41Sopenharmony_ci  DCHECK(function->is_compiled());
21311cb0ef41Sopenharmony_ci  return true;
21321cb0ef41Sopenharmony_ci}
21331cb0ef41Sopenharmony_ci
21341cb0ef41Sopenharmony_ci// static
21351cb0ef41Sopenharmony_cibool Compiler::CompileSharedWithBaseline(Isolate* isolate,
21361cb0ef41Sopenharmony_ci                                         Handle<SharedFunctionInfo> shared,
21371cb0ef41Sopenharmony_ci                                         Compiler::ClearExceptionFlag flag,
21381cb0ef41Sopenharmony_ci                                         IsCompiledScope* is_compiled_scope) {
21391cb0ef41Sopenharmony_ci  // We shouldn't be passing uncompiled functions into this function.
21401cb0ef41Sopenharmony_ci  DCHECK(is_compiled_scope->is_compiled());
21411cb0ef41Sopenharmony_ci
21421cb0ef41Sopenharmony_ci  // Early return for already baseline-compiled functions.
21431cb0ef41Sopenharmony_ci  if (shared->HasBaselineCode()) return true;
21441cb0ef41Sopenharmony_ci
21451cb0ef41Sopenharmony_ci  // Check if we actually can compile with baseline.
21461cb0ef41Sopenharmony_ci  if (!CanCompileWithBaseline(isolate, *shared)) return false;
21471cb0ef41Sopenharmony_ci
21481cb0ef41Sopenharmony_ci  StackLimitCheck check(isolate);
21491cb0ef41Sopenharmony_ci  if (check.JsHasOverflowed(kStackSpaceRequiredForCompilation * KB)) {
21501cb0ef41Sopenharmony_ci    if (flag == Compiler::KEEP_EXCEPTION) {
21511cb0ef41Sopenharmony_ci      isolate->StackOverflow();
21521cb0ef41Sopenharmony_ci    }
21531cb0ef41Sopenharmony_ci    return false;
21541cb0ef41Sopenharmony_ci  }
21551cb0ef41Sopenharmony_ci
21561cb0ef41Sopenharmony_ci  CompilerTracer::TraceStartBaselineCompile(isolate, shared);
21571cb0ef41Sopenharmony_ci  Handle<Code> code;
21581cb0ef41Sopenharmony_ci  base::TimeDelta time_taken;
21591cb0ef41Sopenharmony_ci  {
21601cb0ef41Sopenharmony_ci    ScopedTimer timer(&time_taken);
21611cb0ef41Sopenharmony_ci    if (!GenerateBaselineCode(isolate, shared).ToHandle(&code)) {
21621cb0ef41Sopenharmony_ci      // TODO(leszeks): This can only fail because of an OOM. Do we want to
21631cb0ef41Sopenharmony_ci      // report these somehow, or silently ignore them?
21641cb0ef41Sopenharmony_ci      return false;
21651cb0ef41Sopenharmony_ci    }
21661cb0ef41Sopenharmony_ci    shared->set_baseline_code(ToCodeT(*code), kReleaseStore);
21671cb0ef41Sopenharmony_ci
21681cb0ef41Sopenharmony_ci    if (V8_LIKELY(FLAG_use_osr)) {
21691cb0ef41Sopenharmony_ci      shared->GetBytecodeArray(isolate).RequestOsrAtNextOpportunity();
21701cb0ef41Sopenharmony_ci    }
21711cb0ef41Sopenharmony_ci  }
21721cb0ef41Sopenharmony_ci  double time_taken_ms = time_taken.InMillisecondsF();
21731cb0ef41Sopenharmony_ci
21741cb0ef41Sopenharmony_ci  CompilerTracer::TraceFinishBaselineCompile(isolate, shared, time_taken_ms);
21751cb0ef41Sopenharmony_ci
21761cb0ef41Sopenharmony_ci  if (shared->script().IsScript()) {
21771cb0ef41Sopenharmony_ci    LogFunctionCompilation(isolate, CodeEventListener::FUNCTION_TAG,
21781cb0ef41Sopenharmony_ci                           handle(Script::cast(shared->script()), isolate),
21791cb0ef41Sopenharmony_ci                           shared, Handle<FeedbackVector>(),
21801cb0ef41Sopenharmony_ci                           Handle<AbstractCode>::cast(code), CodeKind::BASELINE,
21811cb0ef41Sopenharmony_ci                           time_taken_ms);
21821cb0ef41Sopenharmony_ci  }
21831cb0ef41Sopenharmony_ci  return true;
21841cb0ef41Sopenharmony_ci}
21851cb0ef41Sopenharmony_ci
21861cb0ef41Sopenharmony_ci// static
21871cb0ef41Sopenharmony_cibool Compiler::CompileBaseline(Isolate* isolate, Handle<JSFunction> function,
21881cb0ef41Sopenharmony_ci                               ClearExceptionFlag flag,
21891cb0ef41Sopenharmony_ci                               IsCompiledScope* is_compiled_scope) {
21901cb0ef41Sopenharmony_ci  Handle<SharedFunctionInfo> shared(function->shared(isolate), isolate);
21911cb0ef41Sopenharmony_ci  if (!CompileSharedWithBaseline(isolate, shared, flag, is_compiled_scope)) {
21921cb0ef41Sopenharmony_ci    return false;
21931cb0ef41Sopenharmony_ci  }
21941cb0ef41Sopenharmony_ci
21951cb0ef41Sopenharmony_ci  // Baseline code needs a feedback vector.
21961cb0ef41Sopenharmony_ci  JSFunction::EnsureFeedbackVector(isolate, function, is_compiled_scope);
21971cb0ef41Sopenharmony_ci
21981cb0ef41Sopenharmony_ci  CodeT baseline_code = shared->baseline_code(kAcquireLoad);
21991cb0ef41Sopenharmony_ci  DCHECK_EQ(baseline_code.kind(), CodeKind::BASELINE);
22001cb0ef41Sopenharmony_ci  function->set_code(baseline_code);
22011cb0ef41Sopenharmony_ci
22021cb0ef41Sopenharmony_ci  return true;
22031cb0ef41Sopenharmony_ci}
22041cb0ef41Sopenharmony_ci
22051cb0ef41Sopenharmony_ci// static
22061cb0ef41Sopenharmony_cibool Compiler::CompileMaglev(Isolate* isolate, Handle<JSFunction> function,
22071cb0ef41Sopenharmony_ci                             ConcurrencyMode mode,
22081cb0ef41Sopenharmony_ci                             IsCompiledScope* is_compiled_scope) {
22091cb0ef41Sopenharmony_ci#ifdef V8_ENABLE_MAGLEV
22101cb0ef41Sopenharmony_ci  // Bytecode must be available for maglev compilation.
22111cb0ef41Sopenharmony_ci  DCHECK(is_compiled_scope->is_compiled());
22121cb0ef41Sopenharmony_ci  // TODO(v8:7700): Support concurrent compilation.
22131cb0ef41Sopenharmony_ci  DCHECK(IsSynchronous(mode));
22141cb0ef41Sopenharmony_ci
22151cb0ef41Sopenharmony_ci  // Maglev code needs a feedback vector.
22161cb0ef41Sopenharmony_ci  JSFunction::EnsureFeedbackVector(isolate, function, is_compiled_scope);
22171cb0ef41Sopenharmony_ci
22181cb0ef41Sopenharmony_ci  MaybeHandle<CodeT> maybe_code = Maglev::Compile(isolate, function);
22191cb0ef41Sopenharmony_ci  Handle<CodeT> code;
22201cb0ef41Sopenharmony_ci  if (!maybe_code.ToHandle(&code)) return false;
22211cb0ef41Sopenharmony_ci
22221cb0ef41Sopenharmony_ci  DCHECK_EQ(code->kind(), CodeKind::MAGLEV);
22231cb0ef41Sopenharmony_ci  function->set_code(*code);
22241cb0ef41Sopenharmony_ci
22251cb0ef41Sopenharmony_ci  return true;
22261cb0ef41Sopenharmony_ci#else
22271cb0ef41Sopenharmony_ci  return false;
22281cb0ef41Sopenharmony_ci#endif  // V8_ENABLE_MAGLEV
22291cb0ef41Sopenharmony_ci}
22301cb0ef41Sopenharmony_ci
22311cb0ef41Sopenharmony_ci// static
22321cb0ef41Sopenharmony_ciMaybeHandle<SharedFunctionInfo> Compiler::CompileToplevel(
22331cb0ef41Sopenharmony_ci    ParseInfo* parse_info, Handle<Script> script, Isolate* isolate,
22341cb0ef41Sopenharmony_ci    IsCompiledScope* is_compiled_scope) {
22351cb0ef41Sopenharmony_ci  return v8::internal::CompileToplevel(parse_info, script, kNullMaybeHandle,
22361cb0ef41Sopenharmony_ci                                       isolate, is_compiled_scope);
22371cb0ef41Sopenharmony_ci}
22381cb0ef41Sopenharmony_ci
22391cb0ef41Sopenharmony_ci// static
22401cb0ef41Sopenharmony_cibool Compiler::FinalizeBackgroundCompileTask(BackgroundCompileTask* task,
22411cb0ef41Sopenharmony_ci                                             Isolate* isolate,
22421cb0ef41Sopenharmony_ci                                             ClearExceptionFlag flag) {
22431cb0ef41Sopenharmony_ci  TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.compile"),
22441cb0ef41Sopenharmony_ci               "V8.FinalizeBackgroundCompileTask");
22451cb0ef41Sopenharmony_ci  RCS_SCOPE(isolate,
22461cb0ef41Sopenharmony_ci            RuntimeCallCounterId::kCompileFinalizeBackgroundCompileTask);
22471cb0ef41Sopenharmony_ci
22481cb0ef41Sopenharmony_ci  HandleScope scope(isolate);
22491cb0ef41Sopenharmony_ci
22501cb0ef41Sopenharmony_ci  if (!task->FinalizeFunction(isolate, flag)) return false;
22511cb0ef41Sopenharmony_ci
22521cb0ef41Sopenharmony_ci  DCHECK(!isolate->has_pending_exception());
22531cb0ef41Sopenharmony_ci  return true;
22541cb0ef41Sopenharmony_ci}
22551cb0ef41Sopenharmony_ci
22561cb0ef41Sopenharmony_ci// static
22571cb0ef41Sopenharmony_civoid Compiler::CompileOptimized(Isolate* isolate, Handle<JSFunction> function,
22581cb0ef41Sopenharmony_ci                                ConcurrencyMode mode, CodeKind code_kind) {
22591cb0ef41Sopenharmony_ci  DCHECK(CodeKindIsOptimizedJSFunction(code_kind));
22601cb0ef41Sopenharmony_ci  DCHECK(AllowCompilation::IsAllowed(isolate));
22611cb0ef41Sopenharmony_ci
22621cb0ef41Sopenharmony_ci  if (FLAG_stress_concurrent_inlining &&
22631cb0ef41Sopenharmony_ci      isolate->concurrent_recompilation_enabled() && IsSynchronous(mode) &&
22641cb0ef41Sopenharmony_ci      isolate->node_observer() == nullptr) {
22651cb0ef41Sopenharmony_ci    SpawnDuplicateConcurrentJobForStressTesting(isolate, function, mode,
22661cb0ef41Sopenharmony_ci                                                code_kind);
22671cb0ef41Sopenharmony_ci  }
22681cb0ef41Sopenharmony_ci
22691cb0ef41Sopenharmony_ci  Handle<CodeT> code;
22701cb0ef41Sopenharmony_ci  if (GetOrCompileOptimized(isolate, function, mode, code_kind)
22711cb0ef41Sopenharmony_ci          .ToHandle(&code)) {
22721cb0ef41Sopenharmony_ci    function->set_code(*code, kReleaseStore);
22731cb0ef41Sopenharmony_ci  }
22741cb0ef41Sopenharmony_ci
22751cb0ef41Sopenharmony_ci#ifdef DEBUG
22761cb0ef41Sopenharmony_ci  DCHECK(!isolate->has_pending_exception());
22771cb0ef41Sopenharmony_ci  DCHECK(function->is_compiled());
22781cb0ef41Sopenharmony_ci  DCHECK(function->shared().HasBytecodeArray());
22791cb0ef41Sopenharmony_ci  const TieringState tiering_state = function->tiering_state();
22801cb0ef41Sopenharmony_ci  DCHECK(IsNone(tiering_state) || IsInProgress(tiering_state));
22811cb0ef41Sopenharmony_ci  DCHECK_IMPLIES(IsInProgress(tiering_state), function->ChecksTieringState());
22821cb0ef41Sopenharmony_ci  DCHECK_IMPLIES(IsInProgress(tiering_state), IsConcurrent(mode));
22831cb0ef41Sopenharmony_ci#endif  // DEBUG
22841cb0ef41Sopenharmony_ci}
22851cb0ef41Sopenharmony_ci
22861cb0ef41Sopenharmony_ci// static
22871cb0ef41Sopenharmony_ciMaybeHandle<SharedFunctionInfo> Compiler::CompileForLiveEdit(
22881cb0ef41Sopenharmony_ci    ParseInfo* parse_info, Handle<Script> script, Isolate* isolate) {
22891cb0ef41Sopenharmony_ci  IsCompiledScope is_compiled_scope;
22901cb0ef41Sopenharmony_ci  return Compiler::CompileToplevel(parse_info, script, isolate,
22911cb0ef41Sopenharmony_ci                                   &is_compiled_scope);
22921cb0ef41Sopenharmony_ci}
22931cb0ef41Sopenharmony_ci
22941cb0ef41Sopenharmony_ci// static
22951cb0ef41Sopenharmony_ciMaybeHandle<JSFunction> Compiler::GetFunctionFromEval(
22961cb0ef41Sopenharmony_ci    Handle<String> source, Handle<SharedFunctionInfo> outer_info,
22971cb0ef41Sopenharmony_ci    Handle<Context> context, LanguageMode language_mode,
22981cb0ef41Sopenharmony_ci    ParseRestriction restriction, int parameters_end_pos,
22991cb0ef41Sopenharmony_ci    int eval_scope_position, int eval_position,
23001cb0ef41Sopenharmony_ci    ParsingWhileDebugging parsing_while_debugging) {
23011cb0ef41Sopenharmony_ci  Isolate* isolate = context->GetIsolate();
23021cb0ef41Sopenharmony_ci  int source_length = source->length();
23031cb0ef41Sopenharmony_ci  isolate->counters()->total_eval_size()->Increment(source_length);
23041cb0ef41Sopenharmony_ci  isolate->counters()->total_compile_size()->Increment(source_length);
23051cb0ef41Sopenharmony_ci
23061cb0ef41Sopenharmony_ci  // The cache lookup key needs to be aware of the separation between the
23071cb0ef41Sopenharmony_ci  // parameters and the body to prevent this valid invocation:
23081cb0ef41Sopenharmony_ci  //   Function("", "function anonymous(\n/**/) {\n}");
23091cb0ef41Sopenharmony_ci  // from adding an entry that falsely approves this invalid invocation:
23101cb0ef41Sopenharmony_ci  //   Function("\n/**/) {\nfunction anonymous(", "}");
23111cb0ef41Sopenharmony_ci  // The actual eval_scope_position for indirect eval and CreateDynamicFunction
23121cb0ef41Sopenharmony_ci  // is unused (just 0), which means it's an available field to use to indicate
23131cb0ef41Sopenharmony_ci  // this separation. But to make sure we're not causing other false hits, we
23141cb0ef41Sopenharmony_ci  // negate the scope position.
23151cb0ef41Sopenharmony_ci  if (restriction == ONLY_SINGLE_FUNCTION_LITERAL &&
23161cb0ef41Sopenharmony_ci      parameters_end_pos != kNoSourcePosition) {
23171cb0ef41Sopenharmony_ci    // use the parameters_end_pos as the eval_scope_position in the eval cache.
23181cb0ef41Sopenharmony_ci    DCHECK_EQ(eval_scope_position, 0);
23191cb0ef41Sopenharmony_ci    eval_scope_position = -parameters_end_pos;
23201cb0ef41Sopenharmony_ci  }
23211cb0ef41Sopenharmony_ci  CompilationCache* compilation_cache = isolate->compilation_cache();
23221cb0ef41Sopenharmony_ci  InfoCellPair eval_result = compilation_cache->LookupEval(
23231cb0ef41Sopenharmony_ci      source, outer_info, context, language_mode, eval_scope_position);
23241cb0ef41Sopenharmony_ci  Handle<FeedbackCell> feedback_cell;
23251cb0ef41Sopenharmony_ci  if (eval_result.has_feedback_cell()) {
23261cb0ef41Sopenharmony_ci    feedback_cell = handle(eval_result.feedback_cell(), isolate);
23271cb0ef41Sopenharmony_ci  }
23281cb0ef41Sopenharmony_ci
23291cb0ef41Sopenharmony_ci  Handle<SharedFunctionInfo> shared_info;
23301cb0ef41Sopenharmony_ci  Handle<Script> script;
23311cb0ef41Sopenharmony_ci  IsCompiledScope is_compiled_scope;
23321cb0ef41Sopenharmony_ci  bool allow_eval_cache;
23331cb0ef41Sopenharmony_ci  if (eval_result.has_shared()) {
23341cb0ef41Sopenharmony_ci    shared_info = Handle<SharedFunctionInfo>(eval_result.shared(), isolate);
23351cb0ef41Sopenharmony_ci    script = Handle<Script>(Script::cast(shared_info->script()), isolate);
23361cb0ef41Sopenharmony_ci    is_compiled_scope = shared_info->is_compiled_scope(isolate);
23371cb0ef41Sopenharmony_ci    allow_eval_cache = true;
23381cb0ef41Sopenharmony_ci  } else {
23391cb0ef41Sopenharmony_ci    UnoptimizedCompileFlags flags = UnoptimizedCompileFlags::ForToplevelCompile(
23401cb0ef41Sopenharmony_ci        isolate, true, language_mode, REPLMode::kNo, ScriptType::kClassic,
23411cb0ef41Sopenharmony_ci        FLAG_lazy_eval);
23421cb0ef41Sopenharmony_ci    flags.set_is_eval(true);
23431cb0ef41Sopenharmony_ci    flags.set_parsing_while_debugging(parsing_while_debugging);
23441cb0ef41Sopenharmony_ci    DCHECK(!flags.is_module());
23451cb0ef41Sopenharmony_ci    flags.set_parse_restriction(restriction);
23461cb0ef41Sopenharmony_ci
23471cb0ef41Sopenharmony_ci    UnoptimizedCompileState compile_state;
23481cb0ef41Sopenharmony_ci    ReusableUnoptimizedCompileState reusable_state(isolate);
23491cb0ef41Sopenharmony_ci    ParseInfo parse_info(isolate, flags, &compile_state, &reusable_state);
23501cb0ef41Sopenharmony_ci    parse_info.set_parameters_end_pos(parameters_end_pos);
23511cb0ef41Sopenharmony_ci
23521cb0ef41Sopenharmony_ci    MaybeHandle<ScopeInfo> maybe_outer_scope_info;
23531cb0ef41Sopenharmony_ci    if (!context->IsNativeContext()) {
23541cb0ef41Sopenharmony_ci      maybe_outer_scope_info = handle(context->scope_info(), isolate);
23551cb0ef41Sopenharmony_ci    }
23561cb0ef41Sopenharmony_ci    script = parse_info.CreateScript(
23571cb0ef41Sopenharmony_ci        isolate, source, kNullMaybeHandle,
23581cb0ef41Sopenharmony_ci        OriginOptionsForEval(outer_info->script(), parsing_while_debugging));
23591cb0ef41Sopenharmony_ci    script->set_eval_from_shared(*outer_info);
23601cb0ef41Sopenharmony_ci    if (eval_position == kNoSourcePosition) {
23611cb0ef41Sopenharmony_ci      // If the position is missing, attempt to get the code offset by
23621cb0ef41Sopenharmony_ci      // walking the stack. Do not translate the code offset into source
23631cb0ef41Sopenharmony_ci      // position, but store it as negative value for lazy translation.
23641cb0ef41Sopenharmony_ci      StackTraceFrameIterator it(isolate);
23651cb0ef41Sopenharmony_ci      if (!it.done() && it.is_javascript()) {
23661cb0ef41Sopenharmony_ci        FrameSummary summary = it.GetTopValidFrame();
23671cb0ef41Sopenharmony_ci        script->set_eval_from_shared(
23681cb0ef41Sopenharmony_ci            summary.AsJavaScript().function()->shared());
23691cb0ef41Sopenharmony_ci        script->set_origin_options(
23701cb0ef41Sopenharmony_ci            OriginOptionsForEval(*summary.script(), parsing_while_debugging));
23711cb0ef41Sopenharmony_ci        eval_position = -summary.code_offset();
23721cb0ef41Sopenharmony_ci      } else {
23731cb0ef41Sopenharmony_ci        eval_position = 0;
23741cb0ef41Sopenharmony_ci      }
23751cb0ef41Sopenharmony_ci    }
23761cb0ef41Sopenharmony_ci    script->set_eval_from_position(eval_position);
23771cb0ef41Sopenharmony_ci
23781cb0ef41Sopenharmony_ci    if (!v8::internal::CompileToplevel(&parse_info, script,
23791cb0ef41Sopenharmony_ci                                       maybe_outer_scope_info, isolate,
23801cb0ef41Sopenharmony_ci                                       &is_compiled_scope)
23811cb0ef41Sopenharmony_ci             .ToHandle(&shared_info)) {
23821cb0ef41Sopenharmony_ci      return MaybeHandle<JSFunction>();
23831cb0ef41Sopenharmony_ci    }
23841cb0ef41Sopenharmony_ci    allow_eval_cache = parse_info.allow_eval_cache();
23851cb0ef41Sopenharmony_ci  }
23861cb0ef41Sopenharmony_ci
23871cb0ef41Sopenharmony_ci  // If caller is strict mode, the result must be in strict mode as well.
23881cb0ef41Sopenharmony_ci  DCHECK(is_sloppy(language_mode) || is_strict(shared_info->language_mode()));
23891cb0ef41Sopenharmony_ci
23901cb0ef41Sopenharmony_ci  Handle<JSFunction> result;
23911cb0ef41Sopenharmony_ci  if (eval_result.has_shared()) {
23921cb0ef41Sopenharmony_ci    if (eval_result.has_feedback_cell()) {
23931cb0ef41Sopenharmony_ci      result = Factory::JSFunctionBuilder{isolate, shared_info, context}
23941cb0ef41Sopenharmony_ci                   .set_feedback_cell(feedback_cell)
23951cb0ef41Sopenharmony_ci                   .set_allocation_type(AllocationType::kYoung)
23961cb0ef41Sopenharmony_ci                   .Build();
23971cb0ef41Sopenharmony_ci    } else {
23981cb0ef41Sopenharmony_ci      result = Factory::JSFunctionBuilder{isolate, shared_info, context}
23991cb0ef41Sopenharmony_ci                   .set_allocation_type(AllocationType::kYoung)
24001cb0ef41Sopenharmony_ci                   .Build();
24011cb0ef41Sopenharmony_ci      // TODO(mythria): I don't think we need this here. PostInstantiation
24021cb0ef41Sopenharmony_ci      // already initializes feedback cell.
24031cb0ef41Sopenharmony_ci      JSFunction::InitializeFeedbackCell(result, &is_compiled_scope, true);
24041cb0ef41Sopenharmony_ci      if (allow_eval_cache) {
24051cb0ef41Sopenharmony_ci        // Make sure to cache this result.
24061cb0ef41Sopenharmony_ci        Handle<FeedbackCell> new_feedback_cell(result->raw_feedback_cell(),
24071cb0ef41Sopenharmony_ci                                               isolate);
24081cb0ef41Sopenharmony_ci        compilation_cache->PutEval(source, outer_info, context, shared_info,
24091cb0ef41Sopenharmony_ci                                   new_feedback_cell, eval_scope_position);
24101cb0ef41Sopenharmony_ci      }
24111cb0ef41Sopenharmony_ci    }
24121cb0ef41Sopenharmony_ci  } else {
24131cb0ef41Sopenharmony_ci    result = Factory::JSFunctionBuilder{isolate, shared_info, context}
24141cb0ef41Sopenharmony_ci                 .set_allocation_type(AllocationType::kYoung)
24151cb0ef41Sopenharmony_ci                 .Build();
24161cb0ef41Sopenharmony_ci    // TODO(mythria): I don't think we need this here. PostInstantiation
24171cb0ef41Sopenharmony_ci    // already initializes feedback cell.
24181cb0ef41Sopenharmony_ci    JSFunction::InitializeFeedbackCell(result, &is_compiled_scope, true);
24191cb0ef41Sopenharmony_ci    if (allow_eval_cache) {
24201cb0ef41Sopenharmony_ci      // Add the SharedFunctionInfo and the LiteralsArray to the eval cache if
24211cb0ef41Sopenharmony_ci      // we didn't retrieve from there.
24221cb0ef41Sopenharmony_ci      Handle<FeedbackCell> new_feedback_cell(result->raw_feedback_cell(),
24231cb0ef41Sopenharmony_ci                                             isolate);
24241cb0ef41Sopenharmony_ci      compilation_cache->PutEval(source, outer_info, context, shared_info,
24251cb0ef41Sopenharmony_ci                                 new_feedback_cell, eval_scope_position);
24261cb0ef41Sopenharmony_ci    }
24271cb0ef41Sopenharmony_ci  }
24281cb0ef41Sopenharmony_ci  DCHECK(is_compiled_scope.is_compiled());
24291cb0ef41Sopenharmony_ci
24301cb0ef41Sopenharmony_ci  return result;
24311cb0ef41Sopenharmony_ci}
24321cb0ef41Sopenharmony_ci
24331cb0ef41Sopenharmony_ci// Check whether embedder allows code generation in this context.
24341cb0ef41Sopenharmony_ci// (via v8::Isolate::SetAllowCodeGenerationFromStringsCallback)
24351cb0ef41Sopenharmony_cibool CodeGenerationFromStringsAllowed(Isolate* isolate, Handle<Context> context,
24361cb0ef41Sopenharmony_ci                                      Handle<String> source) {
24371cb0ef41Sopenharmony_ci  RCS_SCOPE(isolate, RuntimeCallCounterId::kCodeGenerationFromStringsCallbacks);
24381cb0ef41Sopenharmony_ci  DCHECK(context->allow_code_gen_from_strings().IsFalse(isolate));
24391cb0ef41Sopenharmony_ci  DCHECK(isolate->allow_code_gen_callback());
24401cb0ef41Sopenharmony_ci  AllowCodeGenerationFromStringsCallback callback =
24411cb0ef41Sopenharmony_ci      isolate->allow_code_gen_callback();
24421cb0ef41Sopenharmony_ci  ExternalCallbackScope external_callback(isolate,
24431cb0ef41Sopenharmony_ci                                          reinterpret_cast<Address>(callback));
24441cb0ef41Sopenharmony_ci  // Callback set. Let it decide if code generation is allowed.
24451cb0ef41Sopenharmony_ci  return callback(v8::Utils::ToLocal(context), v8::Utils::ToLocal(source));
24461cb0ef41Sopenharmony_ci}
24471cb0ef41Sopenharmony_ci
24481cb0ef41Sopenharmony_ci// Check whether embedder allows code generation in this context.
24491cb0ef41Sopenharmony_ci// (via v8::Isolate::SetModifyCodeGenerationFromStringsCallback
24501cb0ef41Sopenharmony_ci//  or v8::Isolate::SetModifyCodeGenerationFromStringsCallback2)
24511cb0ef41Sopenharmony_cibool ModifyCodeGenerationFromStrings(Isolate* isolate, Handle<Context> context,
24521cb0ef41Sopenharmony_ci                                     Handle<i::Object>* source,
24531cb0ef41Sopenharmony_ci                                     bool is_code_like) {
24541cb0ef41Sopenharmony_ci  DCHECK(isolate->modify_code_gen_callback() ||
24551cb0ef41Sopenharmony_ci         isolate->modify_code_gen_callback2());
24561cb0ef41Sopenharmony_ci  DCHECK(source);
24571cb0ef41Sopenharmony_ci
24581cb0ef41Sopenharmony_ci  // Callback set. Run it, and use the return value as source, or block
24591cb0ef41Sopenharmony_ci  // execution if it's not set.
24601cb0ef41Sopenharmony_ci  VMState<EXTERNAL> state(isolate);
24611cb0ef41Sopenharmony_ci  RCS_SCOPE(isolate, RuntimeCallCounterId::kCodeGenerationFromStringsCallbacks);
24621cb0ef41Sopenharmony_ci  ModifyCodeGenerationFromStringsResult result =
24631cb0ef41Sopenharmony_ci      isolate->modify_code_gen_callback()
24641cb0ef41Sopenharmony_ci          ? isolate->modify_code_gen_callback()(v8::Utils::ToLocal(context),
24651cb0ef41Sopenharmony_ci                                                v8::Utils::ToLocal(*source))
24661cb0ef41Sopenharmony_ci          : isolate->modify_code_gen_callback2()(v8::Utils::ToLocal(context),
24671cb0ef41Sopenharmony_ci                                                 v8::Utils::ToLocal(*source),
24681cb0ef41Sopenharmony_ci                                                 is_code_like);
24691cb0ef41Sopenharmony_ci  if (result.codegen_allowed && !result.modified_source.IsEmpty()) {
24701cb0ef41Sopenharmony_ci    // Use the new source (which might be the same as the old source).
24711cb0ef41Sopenharmony_ci    *source =
24721cb0ef41Sopenharmony_ci        Utils::OpenHandle(*result.modified_source.ToLocalChecked(), false);
24731cb0ef41Sopenharmony_ci  }
24741cb0ef41Sopenharmony_ci  return result.codegen_allowed;
24751cb0ef41Sopenharmony_ci}
24761cb0ef41Sopenharmony_ci
24771cb0ef41Sopenharmony_ci// Run Embedder-mandated checks before generating code from a string.
24781cb0ef41Sopenharmony_ci//
24791cb0ef41Sopenharmony_ci// Returns a string to be used for compilation, or a flag that an object type
24801cb0ef41Sopenharmony_ci// was encountered that is neither a string, nor something the embedder knows
24811cb0ef41Sopenharmony_ci// how to handle.
24821cb0ef41Sopenharmony_ci//
24831cb0ef41Sopenharmony_ci// Returns: (assuming: std::tie(source, unknown_object))
24841cb0ef41Sopenharmony_ci// - !source.is_null(): compilation allowed, source contains the source string.
24851cb0ef41Sopenharmony_ci// - unknown_object is true: compilation allowed, but we don't know how to
24861cb0ef41Sopenharmony_ci//                           deal with source_object.
24871cb0ef41Sopenharmony_ci// - source.is_null() && !unknown_object: compilation should be blocked.
24881cb0ef41Sopenharmony_ci//
24891cb0ef41Sopenharmony_ci// - !source_is_null() and unknown_object can't be true at the same time.
24901cb0ef41Sopenharmony_ci
24911cb0ef41Sopenharmony_ci// static
24921cb0ef41Sopenharmony_cistd::pair<MaybeHandle<String>, bool> Compiler::ValidateDynamicCompilationSource(
24931cb0ef41Sopenharmony_ci    Isolate* isolate, Handle<Context> context,
24941cb0ef41Sopenharmony_ci    Handle<i::Object> original_source, bool is_code_like) {
24951cb0ef41Sopenharmony_ci  // Check if the context unconditionally allows code gen from strings.
24961cb0ef41Sopenharmony_ci  // allow_code_gen_from_strings can be many things, so we'll always check
24971cb0ef41Sopenharmony_ci  // against the 'false' literal, so that e.g. undefined and 'true' are treated
24981cb0ef41Sopenharmony_ci  // the same.
24991cb0ef41Sopenharmony_ci  if (!context->allow_code_gen_from_strings().IsFalse(isolate) &&
25001cb0ef41Sopenharmony_ci      original_source->IsString()) {
25011cb0ef41Sopenharmony_ci    return {Handle<String>::cast(original_source), false};
25021cb0ef41Sopenharmony_ci  }
25031cb0ef41Sopenharmony_ci
25041cb0ef41Sopenharmony_ci  // Check if the context allows code generation for this string.
25051cb0ef41Sopenharmony_ci  // allow_code_gen_callback only allows proper strings.
25061cb0ef41Sopenharmony_ci  // (I.e., let allow_code_gen_callback decide, if it has been set.)
25071cb0ef41Sopenharmony_ci  if (isolate->allow_code_gen_callback()) {
25081cb0ef41Sopenharmony_ci    // If we run into this condition, the embedder has marked some object
25091cb0ef41Sopenharmony_ci    // templates as "code like", but has given us a callback that only accepts
25101cb0ef41Sopenharmony_ci    // strings. That makes no sense.
25111cb0ef41Sopenharmony_ci    DCHECK(!original_source->IsCodeLike(isolate));
25121cb0ef41Sopenharmony_ci
25131cb0ef41Sopenharmony_ci    if (!original_source->IsString()) {
25141cb0ef41Sopenharmony_ci      return {MaybeHandle<String>(), true};
25151cb0ef41Sopenharmony_ci    }
25161cb0ef41Sopenharmony_ci    Handle<String> string_source = Handle<String>::cast(original_source);
25171cb0ef41Sopenharmony_ci    if (!CodeGenerationFromStringsAllowed(isolate, context, string_source)) {
25181cb0ef41Sopenharmony_ci      return {MaybeHandle<String>(), false};
25191cb0ef41Sopenharmony_ci    }
25201cb0ef41Sopenharmony_ci    return {string_source, false};
25211cb0ef41Sopenharmony_ci  }
25221cb0ef41Sopenharmony_ci
25231cb0ef41Sopenharmony_ci  // Check if the context wants to block or modify this source object.
25241cb0ef41Sopenharmony_ci  // Double-check that we really have a string now.
25251cb0ef41Sopenharmony_ci  // (Let modify_code_gen_callback decide, if it's been set.)
25261cb0ef41Sopenharmony_ci  if (isolate->modify_code_gen_callback() ||
25271cb0ef41Sopenharmony_ci      isolate->modify_code_gen_callback2()) {
25281cb0ef41Sopenharmony_ci    Handle<i::Object> modified_source = original_source;
25291cb0ef41Sopenharmony_ci    if (!ModifyCodeGenerationFromStrings(isolate, context, &modified_source,
25301cb0ef41Sopenharmony_ci                                         is_code_like)) {
25311cb0ef41Sopenharmony_ci      return {MaybeHandle<String>(), false};
25321cb0ef41Sopenharmony_ci    }
25331cb0ef41Sopenharmony_ci    if (!modified_source->IsString()) {
25341cb0ef41Sopenharmony_ci      return {MaybeHandle<String>(), true};
25351cb0ef41Sopenharmony_ci    }
25361cb0ef41Sopenharmony_ci    return {Handle<String>::cast(modified_source), false};
25371cb0ef41Sopenharmony_ci  }
25381cb0ef41Sopenharmony_ci
25391cb0ef41Sopenharmony_ci  if (!context->allow_code_gen_from_strings().IsFalse(isolate) &&
25401cb0ef41Sopenharmony_ci      original_source->IsCodeLike(isolate)) {
25411cb0ef41Sopenharmony_ci    // Codegen is unconditionally allowed, and we're been given a CodeLike
25421cb0ef41Sopenharmony_ci    // object. Stringify.
25431cb0ef41Sopenharmony_ci    MaybeHandle<String> stringified_source =
25441cb0ef41Sopenharmony_ci        Object::ToString(isolate, original_source);
25451cb0ef41Sopenharmony_ci    return {stringified_source, stringified_source.is_null()};
25461cb0ef41Sopenharmony_ci  }
25471cb0ef41Sopenharmony_ci
25481cb0ef41Sopenharmony_ci  // If unconditional codegen was disabled, and no callback defined, we block
25491cb0ef41Sopenharmony_ci  // strings and allow all other objects.
25501cb0ef41Sopenharmony_ci  return {MaybeHandle<String>(), !original_source->IsString()};
25511cb0ef41Sopenharmony_ci}
25521cb0ef41Sopenharmony_ci
25531cb0ef41Sopenharmony_ci// static
25541cb0ef41Sopenharmony_ciMaybeHandle<JSFunction> Compiler::GetFunctionFromValidatedString(
25551cb0ef41Sopenharmony_ci    Handle<Context> context, MaybeHandle<String> source,
25561cb0ef41Sopenharmony_ci    ParseRestriction restriction, int parameters_end_pos) {
25571cb0ef41Sopenharmony_ci  Isolate* const isolate = context->GetIsolate();
25581cb0ef41Sopenharmony_ci  Handle<Context> native_context(context->native_context(), isolate);
25591cb0ef41Sopenharmony_ci
25601cb0ef41Sopenharmony_ci  // Raise an EvalError if we did not receive a string.
25611cb0ef41Sopenharmony_ci  if (source.is_null()) {
25621cb0ef41Sopenharmony_ci    Handle<Object> error_message =
25631cb0ef41Sopenharmony_ci        native_context->ErrorMessageForCodeGenerationFromStrings();
25641cb0ef41Sopenharmony_ci    THROW_NEW_ERROR(
25651cb0ef41Sopenharmony_ci        isolate,
25661cb0ef41Sopenharmony_ci        NewEvalError(MessageTemplate::kCodeGenFromStrings, error_message),
25671cb0ef41Sopenharmony_ci        JSFunction);
25681cb0ef41Sopenharmony_ci  }
25691cb0ef41Sopenharmony_ci
25701cb0ef41Sopenharmony_ci  // Compile source string in the native context.
25711cb0ef41Sopenharmony_ci  int eval_scope_position = 0;
25721cb0ef41Sopenharmony_ci  int eval_position = kNoSourcePosition;
25731cb0ef41Sopenharmony_ci  Handle<SharedFunctionInfo> outer_info(
25741cb0ef41Sopenharmony_ci      native_context->empty_function().shared(), isolate);
25751cb0ef41Sopenharmony_ci  return Compiler::GetFunctionFromEval(source.ToHandleChecked(), outer_info,
25761cb0ef41Sopenharmony_ci                                       native_context, LanguageMode::kSloppy,
25771cb0ef41Sopenharmony_ci                                       restriction, parameters_end_pos,
25781cb0ef41Sopenharmony_ci                                       eval_scope_position, eval_position);
25791cb0ef41Sopenharmony_ci}
25801cb0ef41Sopenharmony_ci
25811cb0ef41Sopenharmony_ci// static
25821cb0ef41Sopenharmony_ciMaybeHandle<JSFunction> Compiler::GetFunctionFromString(
25831cb0ef41Sopenharmony_ci    Handle<Context> context, Handle<Object> source,
25841cb0ef41Sopenharmony_ci    ParseRestriction restriction, int parameters_end_pos, bool is_code_like) {
25851cb0ef41Sopenharmony_ci  Isolate* const isolate = context->GetIsolate();
25861cb0ef41Sopenharmony_ci  MaybeHandle<String> validated_source =
25871cb0ef41Sopenharmony_ci      ValidateDynamicCompilationSource(isolate, context, source, is_code_like)
25881cb0ef41Sopenharmony_ci          .first;
25891cb0ef41Sopenharmony_ci  return GetFunctionFromValidatedString(context, validated_source, restriction,
25901cb0ef41Sopenharmony_ci                                        parameters_end_pos);
25911cb0ef41Sopenharmony_ci}
25921cb0ef41Sopenharmony_ci
25931cb0ef41Sopenharmony_cinamespace {
25941cb0ef41Sopenharmony_ci
25951cb0ef41Sopenharmony_cistruct ScriptCompileTimerScope {
25961cb0ef41Sopenharmony_ci public:
25971cb0ef41Sopenharmony_ci  // TODO(leszeks): There are too many blink-specific entries in this enum,
25981cb0ef41Sopenharmony_ci  // figure out a way to push produce/hit-isolate-cache/consume/consume-failed
25991cb0ef41Sopenharmony_ci  // back up the API and log them in blink instead.
26001cb0ef41Sopenharmony_ci  enum class CacheBehaviour {
26011cb0ef41Sopenharmony_ci    kProduceCodeCache,
26021cb0ef41Sopenharmony_ci    kHitIsolateCacheWhenNoCache,
26031cb0ef41Sopenharmony_ci    kConsumeCodeCache,
26041cb0ef41Sopenharmony_ci    kConsumeCodeCacheFailed,
26051cb0ef41Sopenharmony_ci    kNoCacheBecauseInlineScript,
26061cb0ef41Sopenharmony_ci    kNoCacheBecauseScriptTooSmall,
26071cb0ef41Sopenharmony_ci    kNoCacheBecauseCacheTooCold,
26081cb0ef41Sopenharmony_ci    kNoCacheNoReason,
26091cb0ef41Sopenharmony_ci    kNoCacheBecauseNoResource,
26101cb0ef41Sopenharmony_ci    kNoCacheBecauseInspector,
26111cb0ef41Sopenharmony_ci    kNoCacheBecauseCachingDisabled,
26121cb0ef41Sopenharmony_ci    kNoCacheBecauseModule,
26131cb0ef41Sopenharmony_ci    kNoCacheBecauseStreamingSource,
26141cb0ef41Sopenharmony_ci    kNoCacheBecauseV8Extension,
26151cb0ef41Sopenharmony_ci    kHitIsolateCacheWhenProduceCodeCache,
26161cb0ef41Sopenharmony_ci    kHitIsolateCacheWhenConsumeCodeCache,
26171cb0ef41Sopenharmony_ci    kNoCacheBecauseExtensionModule,
26181cb0ef41Sopenharmony_ci    kNoCacheBecausePacScript,
26191cb0ef41Sopenharmony_ci    kNoCacheBecauseInDocumentWrite,
26201cb0ef41Sopenharmony_ci    kNoCacheBecauseResourceWithNoCacheHandler,
26211cb0ef41Sopenharmony_ci    kHitIsolateCacheWhenStreamingSource,
26221cb0ef41Sopenharmony_ci    kCount
26231cb0ef41Sopenharmony_ci  };
26241cb0ef41Sopenharmony_ci
26251cb0ef41Sopenharmony_ci  explicit ScriptCompileTimerScope(
26261cb0ef41Sopenharmony_ci      Isolate* isolate, ScriptCompiler::NoCacheReason no_cache_reason)
26271cb0ef41Sopenharmony_ci      : isolate_(isolate),
26281cb0ef41Sopenharmony_ci        all_scripts_histogram_scope_(isolate->counters()->compile_script()),
26291cb0ef41Sopenharmony_ci        no_cache_reason_(no_cache_reason),
26301cb0ef41Sopenharmony_ci        hit_isolate_cache_(false),
26311cb0ef41Sopenharmony_ci        producing_code_cache_(false),
26321cb0ef41Sopenharmony_ci        consuming_code_cache_(false),
26331cb0ef41Sopenharmony_ci        consuming_code_cache_failed_(false) {}
26341cb0ef41Sopenharmony_ci
26351cb0ef41Sopenharmony_ci  ~ScriptCompileTimerScope() {
26361cb0ef41Sopenharmony_ci    CacheBehaviour cache_behaviour = GetCacheBehaviour();
26371cb0ef41Sopenharmony_ci
26381cb0ef41Sopenharmony_ci    Histogram* cache_behaviour_histogram =
26391cb0ef41Sopenharmony_ci        isolate_->counters()->compile_script_cache_behaviour();
26401cb0ef41Sopenharmony_ci    // Sanity check that the histogram has exactly one bin per enum entry.
26411cb0ef41Sopenharmony_ci    DCHECK_EQ(0, cache_behaviour_histogram->min());
26421cb0ef41Sopenharmony_ci    DCHECK_EQ(static_cast<int>(CacheBehaviour::kCount),
26431cb0ef41Sopenharmony_ci              cache_behaviour_histogram->max() + 1);
26441cb0ef41Sopenharmony_ci    DCHECK_EQ(static_cast<int>(CacheBehaviour::kCount),
26451cb0ef41Sopenharmony_ci              cache_behaviour_histogram->num_buckets());
26461cb0ef41Sopenharmony_ci    cache_behaviour_histogram->AddSample(static_cast<int>(cache_behaviour));
26471cb0ef41Sopenharmony_ci
26481cb0ef41Sopenharmony_ci    histogram_scope_.set_histogram(
26491cb0ef41Sopenharmony_ci        GetCacheBehaviourTimedHistogram(cache_behaviour));
26501cb0ef41Sopenharmony_ci  }
26511cb0ef41Sopenharmony_ci
26521cb0ef41Sopenharmony_ci  void set_hit_isolate_cache() { hit_isolate_cache_ = true; }
26531cb0ef41Sopenharmony_ci
26541cb0ef41Sopenharmony_ci  void set_producing_code_cache() { producing_code_cache_ = true; }
26551cb0ef41Sopenharmony_ci
26561cb0ef41Sopenharmony_ci  void set_consuming_code_cache() { consuming_code_cache_ = true; }
26571cb0ef41Sopenharmony_ci
26581cb0ef41Sopenharmony_ci  void set_consuming_code_cache_failed() {
26591cb0ef41Sopenharmony_ci    consuming_code_cache_failed_ = true;
26601cb0ef41Sopenharmony_ci  }
26611cb0ef41Sopenharmony_ci
26621cb0ef41Sopenharmony_ci private:
26631cb0ef41Sopenharmony_ci  Isolate* isolate_;
26641cb0ef41Sopenharmony_ci  LazyTimedHistogramScope histogram_scope_;
26651cb0ef41Sopenharmony_ci  // TODO(leszeks): This timer is the sum of the other times, consider removing
26661cb0ef41Sopenharmony_ci  // it to save space.
26671cb0ef41Sopenharmony_ci  NestedTimedHistogramScope all_scripts_histogram_scope_;
26681cb0ef41Sopenharmony_ci  ScriptCompiler::NoCacheReason no_cache_reason_;
26691cb0ef41Sopenharmony_ci  bool hit_isolate_cache_;
26701cb0ef41Sopenharmony_ci  bool producing_code_cache_;
26711cb0ef41Sopenharmony_ci  bool consuming_code_cache_;
26721cb0ef41Sopenharmony_ci  bool consuming_code_cache_failed_;
26731cb0ef41Sopenharmony_ci
26741cb0ef41Sopenharmony_ci  CacheBehaviour GetCacheBehaviour() {
26751cb0ef41Sopenharmony_ci    if (producing_code_cache_) {
26761cb0ef41Sopenharmony_ci      if (hit_isolate_cache_) {
26771cb0ef41Sopenharmony_ci        return CacheBehaviour::kHitIsolateCacheWhenProduceCodeCache;
26781cb0ef41Sopenharmony_ci      } else {
26791cb0ef41Sopenharmony_ci        return CacheBehaviour::kProduceCodeCache;
26801cb0ef41Sopenharmony_ci      }
26811cb0ef41Sopenharmony_ci    }
26821cb0ef41Sopenharmony_ci
26831cb0ef41Sopenharmony_ci    if (consuming_code_cache_) {
26841cb0ef41Sopenharmony_ci      if (hit_isolate_cache_) {
26851cb0ef41Sopenharmony_ci        return CacheBehaviour::kHitIsolateCacheWhenConsumeCodeCache;
26861cb0ef41Sopenharmony_ci      } else if (consuming_code_cache_failed_) {
26871cb0ef41Sopenharmony_ci        return CacheBehaviour::kConsumeCodeCacheFailed;
26881cb0ef41Sopenharmony_ci      }
26891cb0ef41Sopenharmony_ci      return CacheBehaviour::kConsumeCodeCache;
26901cb0ef41Sopenharmony_ci    }
26911cb0ef41Sopenharmony_ci
26921cb0ef41Sopenharmony_ci    if (hit_isolate_cache_) {
26931cb0ef41Sopenharmony_ci      if (no_cache_reason_ == ScriptCompiler::kNoCacheBecauseStreamingSource) {
26941cb0ef41Sopenharmony_ci        return CacheBehaviour::kHitIsolateCacheWhenStreamingSource;
26951cb0ef41Sopenharmony_ci      }
26961cb0ef41Sopenharmony_ci      return CacheBehaviour::kHitIsolateCacheWhenNoCache;
26971cb0ef41Sopenharmony_ci    }
26981cb0ef41Sopenharmony_ci
26991cb0ef41Sopenharmony_ci    switch (no_cache_reason_) {
27001cb0ef41Sopenharmony_ci      case ScriptCompiler::kNoCacheBecauseInlineScript:
27011cb0ef41Sopenharmony_ci        return CacheBehaviour::kNoCacheBecauseInlineScript;
27021cb0ef41Sopenharmony_ci      case ScriptCompiler::kNoCacheBecauseScriptTooSmall:
27031cb0ef41Sopenharmony_ci        return CacheBehaviour::kNoCacheBecauseScriptTooSmall;
27041cb0ef41Sopenharmony_ci      case ScriptCompiler::kNoCacheBecauseCacheTooCold:
27051cb0ef41Sopenharmony_ci        return CacheBehaviour::kNoCacheBecauseCacheTooCold;
27061cb0ef41Sopenharmony_ci      case ScriptCompiler::kNoCacheNoReason:
27071cb0ef41Sopenharmony_ci        return CacheBehaviour::kNoCacheNoReason;
27081cb0ef41Sopenharmony_ci      case ScriptCompiler::kNoCacheBecauseNoResource:
27091cb0ef41Sopenharmony_ci        return CacheBehaviour::kNoCacheBecauseNoResource;
27101cb0ef41Sopenharmony_ci      case ScriptCompiler::kNoCacheBecauseInspector:
27111cb0ef41Sopenharmony_ci        return CacheBehaviour::kNoCacheBecauseInspector;
27121cb0ef41Sopenharmony_ci      case ScriptCompiler::kNoCacheBecauseCachingDisabled:
27131cb0ef41Sopenharmony_ci        return CacheBehaviour::kNoCacheBecauseCachingDisabled;
27141cb0ef41Sopenharmony_ci      case ScriptCompiler::kNoCacheBecauseModule:
27151cb0ef41Sopenharmony_ci        return CacheBehaviour::kNoCacheBecauseModule;
27161cb0ef41Sopenharmony_ci      case ScriptCompiler::kNoCacheBecauseStreamingSource:
27171cb0ef41Sopenharmony_ci        return CacheBehaviour::kNoCacheBecauseStreamingSource;
27181cb0ef41Sopenharmony_ci      case ScriptCompiler::kNoCacheBecauseV8Extension:
27191cb0ef41Sopenharmony_ci        return CacheBehaviour::kNoCacheBecauseV8Extension;
27201cb0ef41Sopenharmony_ci      case ScriptCompiler::kNoCacheBecauseExtensionModule:
27211cb0ef41Sopenharmony_ci        return CacheBehaviour::kNoCacheBecauseExtensionModule;
27221cb0ef41Sopenharmony_ci      case ScriptCompiler::kNoCacheBecausePacScript:
27231cb0ef41Sopenharmony_ci        return CacheBehaviour::kNoCacheBecausePacScript;
27241cb0ef41Sopenharmony_ci      case ScriptCompiler::kNoCacheBecauseInDocumentWrite:
27251cb0ef41Sopenharmony_ci        return CacheBehaviour::kNoCacheBecauseInDocumentWrite;
27261cb0ef41Sopenharmony_ci      case ScriptCompiler::kNoCacheBecauseResourceWithNoCacheHandler:
27271cb0ef41Sopenharmony_ci        return CacheBehaviour::kNoCacheBecauseResourceWithNoCacheHandler;
27281cb0ef41Sopenharmony_ci      case ScriptCompiler::kNoCacheBecauseDeferredProduceCodeCache: {
27291cb0ef41Sopenharmony_ci        if (hit_isolate_cache_) {
27301cb0ef41Sopenharmony_ci          return CacheBehaviour::kHitIsolateCacheWhenProduceCodeCache;
27311cb0ef41Sopenharmony_ci        } else {
27321cb0ef41Sopenharmony_ci          return CacheBehaviour::kProduceCodeCache;
27331cb0ef41Sopenharmony_ci        }
27341cb0ef41Sopenharmony_ci      }
27351cb0ef41Sopenharmony_ci    }
27361cb0ef41Sopenharmony_ci    UNREACHABLE();
27371cb0ef41Sopenharmony_ci  }
27381cb0ef41Sopenharmony_ci
27391cb0ef41Sopenharmony_ci  TimedHistogram* GetCacheBehaviourTimedHistogram(
27401cb0ef41Sopenharmony_ci      CacheBehaviour cache_behaviour) {
27411cb0ef41Sopenharmony_ci    switch (cache_behaviour) {
27421cb0ef41Sopenharmony_ci      case CacheBehaviour::kProduceCodeCache:
27431cb0ef41Sopenharmony_ci      // Even if we hit the isolate's compilation cache, we currently recompile
27441cb0ef41Sopenharmony_ci      // when we want to produce the code cache.
27451cb0ef41Sopenharmony_ci      case CacheBehaviour::kHitIsolateCacheWhenProduceCodeCache:
27461cb0ef41Sopenharmony_ci        return isolate_->counters()->compile_script_with_produce_cache();
27471cb0ef41Sopenharmony_ci      case CacheBehaviour::kHitIsolateCacheWhenNoCache:
27481cb0ef41Sopenharmony_ci      case CacheBehaviour::kHitIsolateCacheWhenConsumeCodeCache:
27491cb0ef41Sopenharmony_ci      case CacheBehaviour::kHitIsolateCacheWhenStreamingSource:
27501cb0ef41Sopenharmony_ci        return isolate_->counters()->compile_script_with_isolate_cache_hit();
27511cb0ef41Sopenharmony_ci      case CacheBehaviour::kConsumeCodeCacheFailed:
27521cb0ef41Sopenharmony_ci        return isolate_->counters()->compile_script_consume_failed();
27531cb0ef41Sopenharmony_ci      case CacheBehaviour::kConsumeCodeCache:
27541cb0ef41Sopenharmony_ci        return isolate_->counters()->compile_script_with_consume_cache();
27551cb0ef41Sopenharmony_ci
27561cb0ef41Sopenharmony_ci      // Note that this only counts the finalization part of streaming, the
27571cb0ef41Sopenharmony_ci      // actual streaming compile is counted by BackgroundCompileTask into
27581cb0ef41Sopenharmony_ci      // "compile_script_on_background".
27591cb0ef41Sopenharmony_ci      case CacheBehaviour::kNoCacheBecauseStreamingSource:
27601cb0ef41Sopenharmony_ci        return isolate_->counters()->compile_script_streaming_finalization();
27611cb0ef41Sopenharmony_ci
27621cb0ef41Sopenharmony_ci      case CacheBehaviour::kNoCacheBecauseInlineScript:
27631cb0ef41Sopenharmony_ci        return isolate_->counters()
27641cb0ef41Sopenharmony_ci            ->compile_script_no_cache_because_inline_script();
27651cb0ef41Sopenharmony_ci      case CacheBehaviour::kNoCacheBecauseScriptTooSmall:
27661cb0ef41Sopenharmony_ci        return isolate_->counters()
27671cb0ef41Sopenharmony_ci            ->compile_script_no_cache_because_script_too_small();
27681cb0ef41Sopenharmony_ci      case CacheBehaviour::kNoCacheBecauseCacheTooCold:
27691cb0ef41Sopenharmony_ci        return isolate_->counters()
27701cb0ef41Sopenharmony_ci            ->compile_script_no_cache_because_cache_too_cold();
27711cb0ef41Sopenharmony_ci
27721cb0ef41Sopenharmony_ci      // Aggregate all the other "no cache" counters into a single histogram, to
27731cb0ef41Sopenharmony_ci      // save space.
27741cb0ef41Sopenharmony_ci      case CacheBehaviour::kNoCacheNoReason:
27751cb0ef41Sopenharmony_ci      case CacheBehaviour::kNoCacheBecauseNoResource:
27761cb0ef41Sopenharmony_ci      case CacheBehaviour::kNoCacheBecauseInspector:
27771cb0ef41Sopenharmony_ci      case CacheBehaviour::kNoCacheBecauseCachingDisabled:
27781cb0ef41Sopenharmony_ci      // TODO(leszeks): Consider counting separately once modules are more
27791cb0ef41Sopenharmony_ci      // common.
27801cb0ef41Sopenharmony_ci      case CacheBehaviour::kNoCacheBecauseModule:
27811cb0ef41Sopenharmony_ci      case CacheBehaviour::kNoCacheBecauseV8Extension:
27821cb0ef41Sopenharmony_ci      case CacheBehaviour::kNoCacheBecauseExtensionModule:
27831cb0ef41Sopenharmony_ci      case CacheBehaviour::kNoCacheBecausePacScript:
27841cb0ef41Sopenharmony_ci      case CacheBehaviour::kNoCacheBecauseInDocumentWrite:
27851cb0ef41Sopenharmony_ci      case CacheBehaviour::kNoCacheBecauseResourceWithNoCacheHandler:
27861cb0ef41Sopenharmony_ci        return isolate_->counters()->compile_script_no_cache_other();
27871cb0ef41Sopenharmony_ci
27881cb0ef41Sopenharmony_ci      case CacheBehaviour::kCount:
27891cb0ef41Sopenharmony_ci        UNREACHABLE();
27901cb0ef41Sopenharmony_ci    }
27911cb0ef41Sopenharmony_ci    UNREACHABLE();
27921cb0ef41Sopenharmony_ci  }
27931cb0ef41Sopenharmony_ci};
27941cb0ef41Sopenharmony_ci
27951cb0ef41Sopenharmony_ciHandle<Script> NewScript(
27961cb0ef41Sopenharmony_ci    Isolate* isolate, ParseInfo* parse_info, Handle<String> source,
27971cb0ef41Sopenharmony_ci    ScriptDetails script_details, NativesFlag natives,
27981cb0ef41Sopenharmony_ci    MaybeHandle<FixedArray> maybe_wrapped_arguments = kNullMaybeHandle) {
27991cb0ef41Sopenharmony_ci  // Create a script object describing the script to be compiled.
28001cb0ef41Sopenharmony_ci  Handle<Script> script =
28011cb0ef41Sopenharmony_ci      parse_info->CreateScript(isolate, source, maybe_wrapped_arguments,
28021cb0ef41Sopenharmony_ci                               script_details.origin_options, natives);
28031cb0ef41Sopenharmony_ci  DisallowGarbageCollection no_gc;
28041cb0ef41Sopenharmony_ci  SetScriptFieldsFromDetails(isolate, *script, script_details, &no_gc);
28051cb0ef41Sopenharmony_ci  LOG(isolate, ScriptDetails(*script));
28061cb0ef41Sopenharmony_ci  return script;
28071cb0ef41Sopenharmony_ci}
28081cb0ef41Sopenharmony_ci
28091cb0ef41Sopenharmony_ciMaybeHandle<SharedFunctionInfo> CompileScriptOnMainThread(
28101cb0ef41Sopenharmony_ci    const UnoptimizedCompileFlags flags, Handle<String> source,
28111cb0ef41Sopenharmony_ci    const ScriptDetails& script_details, NativesFlag natives,
28121cb0ef41Sopenharmony_ci    v8::Extension* extension, Isolate* isolate,
28131cb0ef41Sopenharmony_ci    IsCompiledScope* is_compiled_scope) {
28141cb0ef41Sopenharmony_ci  UnoptimizedCompileState compile_state;
28151cb0ef41Sopenharmony_ci  ReusableUnoptimizedCompileState reusable_state(isolate);
28161cb0ef41Sopenharmony_ci  ParseInfo parse_info(isolate, flags, &compile_state, &reusable_state);
28171cb0ef41Sopenharmony_ci  parse_info.set_extension(extension);
28181cb0ef41Sopenharmony_ci
28191cb0ef41Sopenharmony_ci  Handle<Script> script =
28201cb0ef41Sopenharmony_ci      NewScript(isolate, &parse_info, source, script_details, natives);
28211cb0ef41Sopenharmony_ci  DCHECK_IMPLIES(parse_info.flags().collect_type_profile(),
28221cb0ef41Sopenharmony_ci                 script->IsUserJavaScript());
28231cb0ef41Sopenharmony_ci  DCHECK_EQ(parse_info.flags().is_repl_mode(), script->is_repl_mode());
28241cb0ef41Sopenharmony_ci
28251cb0ef41Sopenharmony_ci  return Compiler::CompileToplevel(&parse_info, script, isolate,
28261cb0ef41Sopenharmony_ci                                   is_compiled_scope);
28271cb0ef41Sopenharmony_ci}
28281cb0ef41Sopenharmony_ci
28291cb0ef41Sopenharmony_ciclass StressBackgroundCompileThread : public base::Thread {
28301cb0ef41Sopenharmony_ci public:
28311cb0ef41Sopenharmony_ci  StressBackgroundCompileThread(Isolate* isolate, Handle<String> source,
28321cb0ef41Sopenharmony_ci                                ScriptType type)
28331cb0ef41Sopenharmony_ci      : base::Thread(
28341cb0ef41Sopenharmony_ci            base::Thread::Options("StressBackgroundCompileThread", 2 * i::MB)),
28351cb0ef41Sopenharmony_ci        source_(source),
28361cb0ef41Sopenharmony_ci        streamed_source_(std::make_unique<SourceStream>(source, isolate),
28371cb0ef41Sopenharmony_ci                         v8::ScriptCompiler::StreamedSource::UTF8) {
28381cb0ef41Sopenharmony_ci    data()->task =
28391cb0ef41Sopenharmony_ci        std::make_unique<i::BackgroundCompileTask>(data(), isolate, type);
28401cb0ef41Sopenharmony_ci  }
28411cb0ef41Sopenharmony_ci
28421cb0ef41Sopenharmony_ci  void Run() override { data()->task->Run(); }
28431cb0ef41Sopenharmony_ci
28441cb0ef41Sopenharmony_ci  ScriptStreamingData* data() { return streamed_source_.impl(); }
28451cb0ef41Sopenharmony_ci
28461cb0ef41Sopenharmony_ci private:
28471cb0ef41Sopenharmony_ci  // Dummy external source stream which returns the whole source in one go.
28481cb0ef41Sopenharmony_ci  // TODO(leszeks): Also test chunking the data.
28491cb0ef41Sopenharmony_ci  class SourceStream : public v8::ScriptCompiler::ExternalSourceStream {
28501cb0ef41Sopenharmony_ci   public:
28511cb0ef41Sopenharmony_ci    SourceStream(Handle<String> source, Isolate* isolate) : done_(false) {
28521cb0ef41Sopenharmony_ci      source_buffer_ = source->ToCString(ALLOW_NULLS, FAST_STRING_TRAVERSAL,
28531cb0ef41Sopenharmony_ci                                         &source_length_);
28541cb0ef41Sopenharmony_ci    }
28551cb0ef41Sopenharmony_ci
28561cb0ef41Sopenharmony_ci    size_t GetMoreData(const uint8_t** src) override {
28571cb0ef41Sopenharmony_ci      if (done_) {
28581cb0ef41Sopenharmony_ci        return 0;
28591cb0ef41Sopenharmony_ci      }
28601cb0ef41Sopenharmony_ci      *src = reinterpret_cast<uint8_t*>(source_buffer_.release());
28611cb0ef41Sopenharmony_ci      done_ = true;
28621cb0ef41Sopenharmony_ci
28631cb0ef41Sopenharmony_ci      return source_length_;
28641cb0ef41Sopenharmony_ci    }
28651cb0ef41Sopenharmony_ci
28661cb0ef41Sopenharmony_ci   private:
28671cb0ef41Sopenharmony_ci    int source_length_;
28681cb0ef41Sopenharmony_ci    std::unique_ptr<char[]> source_buffer_;
28691cb0ef41Sopenharmony_ci    bool done_;
28701cb0ef41Sopenharmony_ci  };
28711cb0ef41Sopenharmony_ci
28721cb0ef41Sopenharmony_ci  Handle<String> source_;
28731cb0ef41Sopenharmony_ci  v8::ScriptCompiler::StreamedSource streamed_source_;
28741cb0ef41Sopenharmony_ci};
28751cb0ef41Sopenharmony_ci
28761cb0ef41Sopenharmony_cibool CanBackgroundCompile(const ScriptDetails& script_details,
28771cb0ef41Sopenharmony_ci                          v8::Extension* extension,
28781cb0ef41Sopenharmony_ci                          ScriptCompiler::CompileOptions compile_options,
28791cb0ef41Sopenharmony_ci                          NativesFlag natives) {
28801cb0ef41Sopenharmony_ci  // TODO(leszeks): Remove the module check once background compilation of
28811cb0ef41Sopenharmony_ci  // modules is supported.
28821cb0ef41Sopenharmony_ci  return !script_details.origin_options.IsModule() && !extension &&
28831cb0ef41Sopenharmony_ci         script_details.repl_mode == REPLMode::kNo &&
28841cb0ef41Sopenharmony_ci         compile_options == ScriptCompiler::kNoCompileOptions &&
28851cb0ef41Sopenharmony_ci         natives == NOT_NATIVES_CODE;
28861cb0ef41Sopenharmony_ci}
28871cb0ef41Sopenharmony_ci
28881cb0ef41Sopenharmony_cibool CompilationExceptionIsRangeError(Isolate* isolate, Handle<Object> obj) {
28891cb0ef41Sopenharmony_ci  if (!obj->IsJSError(isolate)) return false;
28901cb0ef41Sopenharmony_ci  Handle<JSReceiver> js_obj = Handle<JSReceiver>::cast(obj);
28911cb0ef41Sopenharmony_ci  Handle<JSReceiver> constructor;
28921cb0ef41Sopenharmony_ci  if (!JSReceiver::GetConstructor(isolate, js_obj).ToHandle(&constructor)) {
28931cb0ef41Sopenharmony_ci    return false;
28941cb0ef41Sopenharmony_ci  }
28951cb0ef41Sopenharmony_ci  return *constructor == *isolate->range_error_function();
28961cb0ef41Sopenharmony_ci}
28971cb0ef41Sopenharmony_ci
28981cb0ef41Sopenharmony_ciMaybeHandle<SharedFunctionInfo> CompileScriptOnBothBackgroundAndMainThread(
28991cb0ef41Sopenharmony_ci    Handle<String> source, const ScriptDetails& script_details,
29001cb0ef41Sopenharmony_ci    Isolate* isolate, IsCompiledScope* is_compiled_scope) {
29011cb0ef41Sopenharmony_ci  // Start a background thread compiling the script.
29021cb0ef41Sopenharmony_ci  StressBackgroundCompileThread background_compile_thread(
29031cb0ef41Sopenharmony_ci      isolate, source,
29041cb0ef41Sopenharmony_ci      script_details.origin_options.IsModule() ? ScriptType::kModule
29051cb0ef41Sopenharmony_ci                                               : ScriptType::kClassic);
29061cb0ef41Sopenharmony_ci
29071cb0ef41Sopenharmony_ci  UnoptimizedCompileFlags flags_copy =
29081cb0ef41Sopenharmony_ci      background_compile_thread.data()->task->flags();
29091cb0ef41Sopenharmony_ci
29101cb0ef41Sopenharmony_ci  CHECK(background_compile_thread.Start());
29111cb0ef41Sopenharmony_ci  MaybeHandle<SharedFunctionInfo> main_thread_maybe_result;
29121cb0ef41Sopenharmony_ci  bool main_thread_had_stack_overflow = false;
29131cb0ef41Sopenharmony_ci  // In parallel, compile on the main thread to flush out any data races.
29141cb0ef41Sopenharmony_ci  {
29151cb0ef41Sopenharmony_ci    IsCompiledScope inner_is_compiled_scope;
29161cb0ef41Sopenharmony_ci    // The background thread should also create any relevant exceptions, so we
29171cb0ef41Sopenharmony_ci    // can ignore the main-thread created ones.
29181cb0ef41Sopenharmony_ci    // TODO(leszeks): Maybe verify that any thrown (or unthrown) exceptions are
29191cb0ef41Sopenharmony_ci    // equivalent.
29201cb0ef41Sopenharmony_ci    TryCatch ignore_try_catch(reinterpret_cast<v8::Isolate*>(isolate));
29211cb0ef41Sopenharmony_ci    flags_copy.set_script_id(Script::kTemporaryScriptId);
29221cb0ef41Sopenharmony_ci    main_thread_maybe_result = CompileScriptOnMainThread(
29231cb0ef41Sopenharmony_ci        flags_copy, source, script_details, NOT_NATIVES_CODE, nullptr, isolate,
29241cb0ef41Sopenharmony_ci        &inner_is_compiled_scope);
29251cb0ef41Sopenharmony_ci    if (main_thread_maybe_result.is_null()) {
29261cb0ef41Sopenharmony_ci      // Assume all range errors are stack overflows.
29271cb0ef41Sopenharmony_ci      main_thread_had_stack_overflow = CompilationExceptionIsRangeError(
29281cb0ef41Sopenharmony_ci          isolate, handle(isolate->pending_exception(), isolate));
29291cb0ef41Sopenharmony_ci      isolate->clear_pending_exception();
29301cb0ef41Sopenharmony_ci    }
29311cb0ef41Sopenharmony_ci  }
29321cb0ef41Sopenharmony_ci
29331cb0ef41Sopenharmony_ci  // Join with background thread and finalize compilation.
29341cb0ef41Sopenharmony_ci  {
29351cb0ef41Sopenharmony_ci    ParkedScope scope(isolate->main_thread_local_isolate());
29361cb0ef41Sopenharmony_ci    background_compile_thread.Join();
29371cb0ef41Sopenharmony_ci  }
29381cb0ef41Sopenharmony_ci
29391cb0ef41Sopenharmony_ci  MaybeHandle<SharedFunctionInfo> maybe_result =
29401cb0ef41Sopenharmony_ci      Compiler::GetSharedFunctionInfoForStreamedScript(
29411cb0ef41Sopenharmony_ci          isolate, source, script_details, background_compile_thread.data());
29421cb0ef41Sopenharmony_ci
29431cb0ef41Sopenharmony_ci  // Either both compiles should succeed, or both should fail. The one exception
29441cb0ef41Sopenharmony_ci  // to this is that the main-thread compilation might stack overflow while the
29451cb0ef41Sopenharmony_ci  // background compilation doesn't, so relax the check to include this case.
29461cb0ef41Sopenharmony_ci  // TODO(leszeks): Compare the contents of the results of the two compiles.
29471cb0ef41Sopenharmony_ci  if (main_thread_had_stack_overflow) {
29481cb0ef41Sopenharmony_ci    CHECK(main_thread_maybe_result.is_null());
29491cb0ef41Sopenharmony_ci  } else {
29501cb0ef41Sopenharmony_ci    CHECK_EQ(maybe_result.is_null(), main_thread_maybe_result.is_null());
29511cb0ef41Sopenharmony_ci  }
29521cb0ef41Sopenharmony_ci
29531cb0ef41Sopenharmony_ci  Handle<SharedFunctionInfo> result;
29541cb0ef41Sopenharmony_ci  if (maybe_result.ToHandle(&result)) {
29551cb0ef41Sopenharmony_ci    // The BackgroundCompileTask's IsCompiledScope will keep the result alive
29561cb0ef41Sopenharmony_ci    // until it dies at the end of this function, after which this new
29571cb0ef41Sopenharmony_ci    // IsCompiledScope can take over.
29581cb0ef41Sopenharmony_ci    *is_compiled_scope = result->is_compiled_scope(isolate);
29591cb0ef41Sopenharmony_ci  }
29601cb0ef41Sopenharmony_ci
29611cb0ef41Sopenharmony_ci  return maybe_result;
29621cb0ef41Sopenharmony_ci}
29631cb0ef41Sopenharmony_ci
29641cb0ef41Sopenharmony_ciMaybeHandle<SharedFunctionInfo> GetSharedFunctionInfoForScriptImpl(
29651cb0ef41Sopenharmony_ci    Isolate* isolate, Handle<String> source,
29661cb0ef41Sopenharmony_ci    const ScriptDetails& script_details, v8::Extension* extension,
29671cb0ef41Sopenharmony_ci    AlignedCachedData* cached_data, BackgroundDeserializeTask* deserialize_task,
29681cb0ef41Sopenharmony_ci    ScriptCompiler::CompileOptions compile_options,
29691cb0ef41Sopenharmony_ci    ScriptCompiler::NoCacheReason no_cache_reason, NativesFlag natives) {
29701cb0ef41Sopenharmony_ci  ScriptCompileTimerScope compile_timer(isolate, no_cache_reason);
29711cb0ef41Sopenharmony_ci
29721cb0ef41Sopenharmony_ci  if (compile_options == ScriptCompiler::kNoCompileOptions ||
29731cb0ef41Sopenharmony_ci      compile_options == ScriptCompiler::kEagerCompile) {
29741cb0ef41Sopenharmony_ci    DCHECK_NULL(cached_data);
29751cb0ef41Sopenharmony_ci    DCHECK_NULL(deserialize_task);
29761cb0ef41Sopenharmony_ci  } else {
29771cb0ef41Sopenharmony_ci    DCHECK_EQ(compile_options, ScriptCompiler::kConsumeCodeCache);
29781cb0ef41Sopenharmony_ci    // Have to have exactly one of cached_data or deserialize_task.
29791cb0ef41Sopenharmony_ci    DCHECK(cached_data || deserialize_task);
29801cb0ef41Sopenharmony_ci    DCHECK(!(cached_data && deserialize_task));
29811cb0ef41Sopenharmony_ci    DCHECK_NULL(extension);
29821cb0ef41Sopenharmony_ci  }
29831cb0ef41Sopenharmony_ci  int source_length = source->length();
29841cb0ef41Sopenharmony_ci  isolate->counters()->total_load_size()->Increment(source_length);
29851cb0ef41Sopenharmony_ci  isolate->counters()->total_compile_size()->Increment(source_length);
29861cb0ef41Sopenharmony_ci
29871cb0ef41Sopenharmony_ci  if (V8_UNLIKELY(
29881cb0ef41Sopenharmony_ci          i::FLAG_experimental_web_snapshots &&
29891cb0ef41Sopenharmony_ci          (source->IsExternalOneByteString() || source->IsSeqOneByteString() ||
29901cb0ef41Sopenharmony_ci           source->IsExternalTwoByteString() || source->IsSeqTwoByteString()) &&
29911cb0ef41Sopenharmony_ci          source_length > 4)) {
29921cb0ef41Sopenharmony_ci    // Experimental: Treat the script as a web snapshot if it starts with the
29931cb0ef41Sopenharmony_ci    // magic byte sequence. TODO(v8:11525): Remove this once proper embedder
29941cb0ef41Sopenharmony_ci    // integration is done.
29951cb0ef41Sopenharmony_ci    bool magic_matches = true;
29961cb0ef41Sopenharmony_ci    for (size_t i = 0;
29971cb0ef41Sopenharmony_ci         i < sizeof(WebSnapshotSerializerDeserializer::kMagicNumber); ++i) {
29981cb0ef41Sopenharmony_ci      if (source->Get(static_cast<int>(i)) !=
29991cb0ef41Sopenharmony_ci          WebSnapshotSerializerDeserializer::kMagicNumber[i]) {
30001cb0ef41Sopenharmony_ci        magic_matches = false;
30011cb0ef41Sopenharmony_ci        break;
30021cb0ef41Sopenharmony_ci      }
30031cb0ef41Sopenharmony_ci    }
30041cb0ef41Sopenharmony_ci    if (magic_matches) {
30051cb0ef41Sopenharmony_ci      return Compiler::GetSharedFunctionInfoForWebSnapshot(
30061cb0ef41Sopenharmony_ci          isolate, source, script_details.name_obj);
30071cb0ef41Sopenharmony_ci    }
30081cb0ef41Sopenharmony_ci  }
30091cb0ef41Sopenharmony_ci
30101cb0ef41Sopenharmony_ci  LanguageMode language_mode = construct_language_mode(FLAG_use_strict);
30111cb0ef41Sopenharmony_ci  CompilationCache* compilation_cache = isolate->compilation_cache();
30121cb0ef41Sopenharmony_ci
30131cb0ef41Sopenharmony_ci  // For extensions or REPL mode scripts neither do a compilation cache lookup,
30141cb0ef41Sopenharmony_ci  // nor put the compilation result back into the cache.
30151cb0ef41Sopenharmony_ci  const bool use_compilation_cache =
30161cb0ef41Sopenharmony_ci      extension == nullptr && script_details.repl_mode == REPLMode::kNo;
30171cb0ef41Sopenharmony_ci  MaybeHandle<SharedFunctionInfo> maybe_result;
30181cb0ef41Sopenharmony_ci  IsCompiledScope is_compiled_scope;
30191cb0ef41Sopenharmony_ci  if (use_compilation_cache) {
30201cb0ef41Sopenharmony_ci    bool can_consume_code_cache =
30211cb0ef41Sopenharmony_ci        compile_options == ScriptCompiler::kConsumeCodeCache;
30221cb0ef41Sopenharmony_ci    if (can_consume_code_cache) {
30231cb0ef41Sopenharmony_ci      compile_timer.set_consuming_code_cache();
30241cb0ef41Sopenharmony_ci    }
30251cb0ef41Sopenharmony_ci
30261cb0ef41Sopenharmony_ci    // First check per-isolate compilation cache.
30271cb0ef41Sopenharmony_ci    maybe_result =
30281cb0ef41Sopenharmony_ci        compilation_cache->LookupScript(source, script_details, language_mode);
30291cb0ef41Sopenharmony_ci    if (!maybe_result.is_null()) {
30301cb0ef41Sopenharmony_ci      compile_timer.set_hit_isolate_cache();
30311cb0ef41Sopenharmony_ci    } else if (can_consume_code_cache) {
30321cb0ef41Sopenharmony_ci      compile_timer.set_consuming_code_cache();
30331cb0ef41Sopenharmony_ci      // Then check cached code provided by embedder.
30341cb0ef41Sopenharmony_ci      NestedTimedHistogramScope timer(
30351cb0ef41Sopenharmony_ci          isolate->counters()->compile_deserialize());
30361cb0ef41Sopenharmony_ci      RCS_SCOPE(isolate, RuntimeCallCounterId::kCompileDeserialize);
30371cb0ef41Sopenharmony_ci      TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.compile"),
30381cb0ef41Sopenharmony_ci                   "V8.CompileDeserialize");
30391cb0ef41Sopenharmony_ci      if (deserialize_task) {
30401cb0ef41Sopenharmony_ci        // If there's a cache consume task, finish it.
30411cb0ef41Sopenharmony_ci        maybe_result = deserialize_task->Finish(isolate, source,
30421cb0ef41Sopenharmony_ci                                                script_details.origin_options);
30431cb0ef41Sopenharmony_ci      } else {
30441cb0ef41Sopenharmony_ci        maybe_result = CodeSerializer::Deserialize(
30451cb0ef41Sopenharmony_ci            isolate, cached_data, source, script_details.origin_options);
30461cb0ef41Sopenharmony_ci      }
30471cb0ef41Sopenharmony_ci
30481cb0ef41Sopenharmony_ci      bool consuming_code_cache_succeeded = false;
30491cb0ef41Sopenharmony_ci      Handle<SharedFunctionInfo> result;
30501cb0ef41Sopenharmony_ci      if (maybe_result.ToHandle(&result)) {
30511cb0ef41Sopenharmony_ci        is_compiled_scope = result->is_compiled_scope(isolate);
30521cb0ef41Sopenharmony_ci        if (is_compiled_scope.is_compiled()) {
30531cb0ef41Sopenharmony_ci          consuming_code_cache_succeeded = true;
30541cb0ef41Sopenharmony_ci          // Promote to per-isolate compilation cache.
30551cb0ef41Sopenharmony_ci          compilation_cache->PutScript(source, language_mode, result);
30561cb0ef41Sopenharmony_ci        }
30571cb0ef41Sopenharmony_ci      }
30581cb0ef41Sopenharmony_ci      if (!consuming_code_cache_succeeded) {
30591cb0ef41Sopenharmony_ci        // Deserializer failed. Fall through to compile.
30601cb0ef41Sopenharmony_ci        compile_timer.set_consuming_code_cache_failed();
30611cb0ef41Sopenharmony_ci      }
30621cb0ef41Sopenharmony_ci    }
30631cb0ef41Sopenharmony_ci  }
30641cb0ef41Sopenharmony_ci
30651cb0ef41Sopenharmony_ci  if (maybe_result.is_null()) {
30661cb0ef41Sopenharmony_ci    // No cache entry found compile the script.
30671cb0ef41Sopenharmony_ci    if (FLAG_stress_background_compile &&
30681cb0ef41Sopenharmony_ci        CanBackgroundCompile(script_details, extension, compile_options,
30691cb0ef41Sopenharmony_ci                             natives)) {
30701cb0ef41Sopenharmony_ci      // If the --stress-background-compile flag is set, do the actual
30711cb0ef41Sopenharmony_ci      // compilation on a background thread, and wait for its result.
30721cb0ef41Sopenharmony_ci      maybe_result = CompileScriptOnBothBackgroundAndMainThread(
30731cb0ef41Sopenharmony_ci          source, script_details, isolate, &is_compiled_scope);
30741cb0ef41Sopenharmony_ci    } else {
30751cb0ef41Sopenharmony_ci      UnoptimizedCompileFlags flags =
30761cb0ef41Sopenharmony_ci          UnoptimizedCompileFlags::ForToplevelCompile(
30771cb0ef41Sopenharmony_ci              isolate, natives == NOT_NATIVES_CODE, language_mode,
30781cb0ef41Sopenharmony_ci              script_details.repl_mode,
30791cb0ef41Sopenharmony_ci              script_details.origin_options.IsModule() ? ScriptType::kModule
30801cb0ef41Sopenharmony_ci                                                       : ScriptType::kClassic,
30811cb0ef41Sopenharmony_ci              FLAG_lazy);
30821cb0ef41Sopenharmony_ci
30831cb0ef41Sopenharmony_ci      flags.set_is_eager(compile_options == ScriptCompiler::kEagerCompile);
30841cb0ef41Sopenharmony_ci
30851cb0ef41Sopenharmony_ci      maybe_result =
30861cb0ef41Sopenharmony_ci          CompileScriptOnMainThread(flags, source, script_details, natives,
30871cb0ef41Sopenharmony_ci                                    extension, isolate, &is_compiled_scope);
30881cb0ef41Sopenharmony_ci    }
30891cb0ef41Sopenharmony_ci
30901cb0ef41Sopenharmony_ci    // Add the result to the isolate cache.
30911cb0ef41Sopenharmony_ci    Handle<SharedFunctionInfo> result;
30921cb0ef41Sopenharmony_ci    if (use_compilation_cache && maybe_result.ToHandle(&result)) {
30931cb0ef41Sopenharmony_ci      DCHECK(is_compiled_scope.is_compiled());
30941cb0ef41Sopenharmony_ci      compilation_cache->PutScript(source, language_mode, result);
30951cb0ef41Sopenharmony_ci    } else if (maybe_result.is_null() && natives != EXTENSION_CODE) {
30961cb0ef41Sopenharmony_ci      isolate->ReportPendingMessages();
30971cb0ef41Sopenharmony_ci    }
30981cb0ef41Sopenharmony_ci  }
30991cb0ef41Sopenharmony_ci
31001cb0ef41Sopenharmony_ci  return maybe_result;
31011cb0ef41Sopenharmony_ci}
31021cb0ef41Sopenharmony_ci
31031cb0ef41Sopenharmony_ci}  // namespace
31041cb0ef41Sopenharmony_ci
31051cb0ef41Sopenharmony_ciMaybeHandle<SharedFunctionInfo> Compiler::GetSharedFunctionInfoForScript(
31061cb0ef41Sopenharmony_ci    Isolate* isolate, Handle<String> source,
31071cb0ef41Sopenharmony_ci    const ScriptDetails& script_details,
31081cb0ef41Sopenharmony_ci    ScriptCompiler::CompileOptions compile_options,
31091cb0ef41Sopenharmony_ci    ScriptCompiler::NoCacheReason no_cache_reason, NativesFlag natives) {
31101cb0ef41Sopenharmony_ci  return GetSharedFunctionInfoForScriptImpl(
31111cb0ef41Sopenharmony_ci      isolate, source, script_details, nullptr, nullptr, nullptr,
31121cb0ef41Sopenharmony_ci      compile_options, no_cache_reason, natives);
31131cb0ef41Sopenharmony_ci}
31141cb0ef41Sopenharmony_ci
31151cb0ef41Sopenharmony_ciMaybeHandle<SharedFunctionInfo>
31161cb0ef41Sopenharmony_ciCompiler::GetSharedFunctionInfoForScriptWithExtension(
31171cb0ef41Sopenharmony_ci    Isolate* isolate, Handle<String> source,
31181cb0ef41Sopenharmony_ci    const ScriptDetails& script_details, v8::Extension* extension,
31191cb0ef41Sopenharmony_ci    ScriptCompiler::CompileOptions compile_options, NativesFlag natives) {
31201cb0ef41Sopenharmony_ci  return GetSharedFunctionInfoForScriptImpl(
31211cb0ef41Sopenharmony_ci      isolate, source, script_details, extension, nullptr, nullptr,
31221cb0ef41Sopenharmony_ci      compile_options, ScriptCompiler::kNoCacheBecauseV8Extension, natives);
31231cb0ef41Sopenharmony_ci}
31241cb0ef41Sopenharmony_ci
31251cb0ef41Sopenharmony_ciMaybeHandle<SharedFunctionInfo>
31261cb0ef41Sopenharmony_ciCompiler::GetSharedFunctionInfoForScriptWithCachedData(
31271cb0ef41Sopenharmony_ci    Isolate* isolate, Handle<String> source,
31281cb0ef41Sopenharmony_ci    const ScriptDetails& script_details, AlignedCachedData* cached_data,
31291cb0ef41Sopenharmony_ci    ScriptCompiler::CompileOptions compile_options,
31301cb0ef41Sopenharmony_ci    ScriptCompiler::NoCacheReason no_cache_reason, NativesFlag natives) {
31311cb0ef41Sopenharmony_ci  return GetSharedFunctionInfoForScriptImpl(
31321cb0ef41Sopenharmony_ci      isolate, source, script_details, nullptr, cached_data, nullptr,
31331cb0ef41Sopenharmony_ci      compile_options, no_cache_reason, natives);
31341cb0ef41Sopenharmony_ci}
31351cb0ef41Sopenharmony_ci
31361cb0ef41Sopenharmony_ciMaybeHandle<SharedFunctionInfo>
31371cb0ef41Sopenharmony_ciCompiler::GetSharedFunctionInfoForScriptWithDeserializeTask(
31381cb0ef41Sopenharmony_ci    Isolate* isolate, Handle<String> source,
31391cb0ef41Sopenharmony_ci    const ScriptDetails& script_details,
31401cb0ef41Sopenharmony_ci    BackgroundDeserializeTask* deserialize_task,
31411cb0ef41Sopenharmony_ci    ScriptCompiler::CompileOptions compile_options,
31421cb0ef41Sopenharmony_ci    ScriptCompiler::NoCacheReason no_cache_reason, NativesFlag natives) {
31431cb0ef41Sopenharmony_ci  return GetSharedFunctionInfoForScriptImpl(
31441cb0ef41Sopenharmony_ci      isolate, source, script_details, nullptr, nullptr, deserialize_task,
31451cb0ef41Sopenharmony_ci      compile_options, no_cache_reason, natives);
31461cb0ef41Sopenharmony_ci}
31471cb0ef41Sopenharmony_ci
31481cb0ef41Sopenharmony_ci// static
31491cb0ef41Sopenharmony_ciMaybeHandle<JSFunction> Compiler::GetWrappedFunction(
31501cb0ef41Sopenharmony_ci    Handle<String> source, Handle<FixedArray> arguments,
31511cb0ef41Sopenharmony_ci    Handle<Context> context, const ScriptDetails& script_details,
31521cb0ef41Sopenharmony_ci    AlignedCachedData* cached_data,
31531cb0ef41Sopenharmony_ci    v8::ScriptCompiler::CompileOptions compile_options,
31541cb0ef41Sopenharmony_ci    v8::ScriptCompiler::NoCacheReason no_cache_reason) {
31551cb0ef41Sopenharmony_ci  Isolate* isolate = context->GetIsolate();
31561cb0ef41Sopenharmony_ci  ScriptCompileTimerScope compile_timer(isolate, no_cache_reason);
31571cb0ef41Sopenharmony_ci
31581cb0ef41Sopenharmony_ci  if (compile_options == ScriptCompiler::kNoCompileOptions ||
31591cb0ef41Sopenharmony_ci      compile_options == ScriptCompiler::kEagerCompile) {
31601cb0ef41Sopenharmony_ci    DCHECK_NULL(cached_data);
31611cb0ef41Sopenharmony_ci  } else {
31621cb0ef41Sopenharmony_ci    DCHECK(compile_options == ScriptCompiler::kConsumeCodeCache);
31631cb0ef41Sopenharmony_ci    DCHECK(cached_data);
31641cb0ef41Sopenharmony_ci  }
31651cb0ef41Sopenharmony_ci
31661cb0ef41Sopenharmony_ci  int source_length = source->length();
31671cb0ef41Sopenharmony_ci  isolate->counters()->total_compile_size()->Increment(source_length);
31681cb0ef41Sopenharmony_ci
31691cb0ef41Sopenharmony_ci  LanguageMode language_mode = construct_language_mode(FLAG_use_strict);
31701cb0ef41Sopenharmony_ci
31711cb0ef41Sopenharmony_ci  MaybeHandle<SharedFunctionInfo> maybe_result;
31721cb0ef41Sopenharmony_ci  bool can_consume_code_cache =
31731cb0ef41Sopenharmony_ci      compile_options == ScriptCompiler::kConsumeCodeCache;
31741cb0ef41Sopenharmony_ci  if (can_consume_code_cache) {
31751cb0ef41Sopenharmony_ci    compile_timer.set_consuming_code_cache();
31761cb0ef41Sopenharmony_ci    // Then check cached code provided by embedder.
31771cb0ef41Sopenharmony_ci    NestedTimedHistogramScope timer(isolate->counters()->compile_deserialize());
31781cb0ef41Sopenharmony_ci    RCS_SCOPE(isolate, RuntimeCallCounterId::kCompileDeserialize);
31791cb0ef41Sopenharmony_ci    TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.compile"),
31801cb0ef41Sopenharmony_ci                 "V8.CompileDeserialize");
31811cb0ef41Sopenharmony_ci    maybe_result = CodeSerializer::Deserialize(isolate, cached_data, source,
31821cb0ef41Sopenharmony_ci                                               script_details.origin_options);
31831cb0ef41Sopenharmony_ci    if (maybe_result.is_null()) {
31841cb0ef41Sopenharmony_ci      // Deserializer failed. Fall through to compile.
31851cb0ef41Sopenharmony_ci      compile_timer.set_consuming_code_cache_failed();
31861cb0ef41Sopenharmony_ci    }
31871cb0ef41Sopenharmony_ci  }
31881cb0ef41Sopenharmony_ci
31891cb0ef41Sopenharmony_ci  Handle<SharedFunctionInfo> wrapped;
31901cb0ef41Sopenharmony_ci  Handle<Script> script;
31911cb0ef41Sopenharmony_ci  IsCompiledScope is_compiled_scope;
31921cb0ef41Sopenharmony_ci  if (!maybe_result.ToHandle(&wrapped)) {
31931cb0ef41Sopenharmony_ci    UnoptimizedCompileFlags flags = UnoptimizedCompileFlags::ForToplevelCompile(
31941cb0ef41Sopenharmony_ci        isolate, true, language_mode, script_details.repl_mode,
31951cb0ef41Sopenharmony_ci        ScriptType::kClassic, FLAG_lazy);
31961cb0ef41Sopenharmony_ci    flags.set_is_eval(true);  // Use an eval scope as declaration scope.
31971cb0ef41Sopenharmony_ci    flags.set_function_syntax_kind(FunctionSyntaxKind::kWrapped);
31981cb0ef41Sopenharmony_ci    // TODO(delphick): Remove this and instead make the wrapped and wrapper
31991cb0ef41Sopenharmony_ci    // functions fully non-lazy instead thus preventing source positions from
32001cb0ef41Sopenharmony_ci    // being omitted.
32011cb0ef41Sopenharmony_ci    flags.set_collect_source_positions(true);
32021cb0ef41Sopenharmony_ci    flags.set_is_eager(compile_options == ScriptCompiler::kEagerCompile);
32031cb0ef41Sopenharmony_ci
32041cb0ef41Sopenharmony_ci    UnoptimizedCompileState compile_state;
32051cb0ef41Sopenharmony_ci    ReusableUnoptimizedCompileState reusable_state(isolate);
32061cb0ef41Sopenharmony_ci    ParseInfo parse_info(isolate, flags, &compile_state, &reusable_state);
32071cb0ef41Sopenharmony_ci
32081cb0ef41Sopenharmony_ci    MaybeHandle<ScopeInfo> maybe_outer_scope_info;
32091cb0ef41Sopenharmony_ci    if (!context->IsNativeContext()) {
32101cb0ef41Sopenharmony_ci      maybe_outer_scope_info = handle(context->scope_info(), isolate);
32111cb0ef41Sopenharmony_ci    }
32121cb0ef41Sopenharmony_ci
32131cb0ef41Sopenharmony_ci    script = NewScript(isolate, &parse_info, source, script_details,
32141cb0ef41Sopenharmony_ci                       NOT_NATIVES_CODE, arguments);
32151cb0ef41Sopenharmony_ci
32161cb0ef41Sopenharmony_ci    Handle<SharedFunctionInfo> top_level;
32171cb0ef41Sopenharmony_ci    maybe_result = v8::internal::CompileToplevel(&parse_info, script,
32181cb0ef41Sopenharmony_ci                                                 maybe_outer_scope_info,
32191cb0ef41Sopenharmony_ci                                                 isolate, &is_compiled_scope);
32201cb0ef41Sopenharmony_ci    if (maybe_result.is_null()) isolate->ReportPendingMessages();
32211cb0ef41Sopenharmony_ci    ASSIGN_RETURN_ON_EXCEPTION(isolate, top_level, maybe_result, JSFunction);
32221cb0ef41Sopenharmony_ci
32231cb0ef41Sopenharmony_ci    SharedFunctionInfo::ScriptIterator infos(isolate, *script);
32241cb0ef41Sopenharmony_ci    for (SharedFunctionInfo info = infos.Next(); !info.is_null();
32251cb0ef41Sopenharmony_ci         info = infos.Next()) {
32261cb0ef41Sopenharmony_ci      if (info.is_wrapped()) {
32271cb0ef41Sopenharmony_ci        wrapped = Handle<SharedFunctionInfo>(info, isolate);
32281cb0ef41Sopenharmony_ci        break;
32291cb0ef41Sopenharmony_ci      }
32301cb0ef41Sopenharmony_ci    }
32311cb0ef41Sopenharmony_ci    DCHECK(!wrapped.is_null());
32321cb0ef41Sopenharmony_ci  } else {
32331cb0ef41Sopenharmony_ci    is_compiled_scope = wrapped->is_compiled_scope(isolate);
32341cb0ef41Sopenharmony_ci    script = Handle<Script>(Script::cast(wrapped->script()), isolate);
32351cb0ef41Sopenharmony_ci  }
32361cb0ef41Sopenharmony_ci  DCHECK(is_compiled_scope.is_compiled());
32371cb0ef41Sopenharmony_ci
32381cb0ef41Sopenharmony_ci  return Factory::JSFunctionBuilder{isolate, wrapped, context}
32391cb0ef41Sopenharmony_ci      .set_allocation_type(AllocationType::kYoung)
32401cb0ef41Sopenharmony_ci      .Build();
32411cb0ef41Sopenharmony_ci}
32421cb0ef41Sopenharmony_ci
32431cb0ef41Sopenharmony_ci// static
32441cb0ef41Sopenharmony_ciMaybeHandle<SharedFunctionInfo>
32451cb0ef41Sopenharmony_ciCompiler::GetSharedFunctionInfoForStreamedScript(
32461cb0ef41Sopenharmony_ci    Isolate* isolate, Handle<String> source,
32471cb0ef41Sopenharmony_ci    const ScriptDetails& script_details, ScriptStreamingData* streaming_data) {
32481cb0ef41Sopenharmony_ci  DCHECK(!script_details.origin_options.IsWasm());
32491cb0ef41Sopenharmony_ci
32501cb0ef41Sopenharmony_ci  ScriptCompileTimerScope compile_timer(
32511cb0ef41Sopenharmony_ci      isolate, ScriptCompiler::kNoCacheBecauseStreamingSource);
32521cb0ef41Sopenharmony_ci  PostponeInterruptsScope postpone(isolate);
32531cb0ef41Sopenharmony_ci
32541cb0ef41Sopenharmony_ci  int source_length = source->length();
32551cb0ef41Sopenharmony_ci  isolate->counters()->total_load_size()->Increment(source_length);
32561cb0ef41Sopenharmony_ci  isolate->counters()->total_compile_size()->Increment(source_length);
32571cb0ef41Sopenharmony_ci
32581cb0ef41Sopenharmony_ci  BackgroundCompileTask* task = streaming_data->task.get();
32591cb0ef41Sopenharmony_ci
32601cb0ef41Sopenharmony_ci  MaybeHandle<SharedFunctionInfo> maybe_result;
32611cb0ef41Sopenharmony_ci  // Check if compile cache already holds the SFI, if so no need to finalize
32621cb0ef41Sopenharmony_ci  // the code compiled on the background thread.
32631cb0ef41Sopenharmony_ci  CompilationCache* compilation_cache = isolate->compilation_cache();
32641cb0ef41Sopenharmony_ci  {
32651cb0ef41Sopenharmony_ci    TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.compile"),
32661cb0ef41Sopenharmony_ci                 "V8.StreamingFinalization.CheckCache");
32671cb0ef41Sopenharmony_ci    maybe_result = compilation_cache->LookupScript(
32681cb0ef41Sopenharmony_ci        source, script_details, task->flags().outer_language_mode());
32691cb0ef41Sopenharmony_ci    if (!maybe_result.is_null()) {
32701cb0ef41Sopenharmony_ci      compile_timer.set_hit_isolate_cache();
32711cb0ef41Sopenharmony_ci    }
32721cb0ef41Sopenharmony_ci  }
32731cb0ef41Sopenharmony_ci
32741cb0ef41Sopenharmony_ci  if (maybe_result.is_null()) {
32751cb0ef41Sopenharmony_ci    // No cache entry found, finalize compilation of the script and add it to
32761cb0ef41Sopenharmony_ci    // the isolate cache.
32771cb0ef41Sopenharmony_ci    RCS_SCOPE(isolate,
32781cb0ef41Sopenharmony_ci              RuntimeCallCounterId::kCompilePublishBackgroundFinalization);
32791cb0ef41Sopenharmony_ci    TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.compile"),
32801cb0ef41Sopenharmony_ci                 "V8.OffThreadFinalization.Publish");
32811cb0ef41Sopenharmony_ci
32821cb0ef41Sopenharmony_ci    maybe_result = task->FinalizeScript(isolate, source, script_details);
32831cb0ef41Sopenharmony_ci
32841cb0ef41Sopenharmony_ci    Handle<SharedFunctionInfo> result;
32851cb0ef41Sopenharmony_ci    if (maybe_result.ToHandle(&result)) {
32861cb0ef41Sopenharmony_ci      // Add compiled code to the isolate cache.
32871cb0ef41Sopenharmony_ci      TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.compile"),
32881cb0ef41Sopenharmony_ci                   "V8.StreamingFinalization.AddToCache");
32891cb0ef41Sopenharmony_ci      compilation_cache->PutScript(source, task->flags().outer_language_mode(),
32901cb0ef41Sopenharmony_ci                                   result);
32911cb0ef41Sopenharmony_ci    }
32921cb0ef41Sopenharmony_ci  }
32931cb0ef41Sopenharmony_ci
32941cb0ef41Sopenharmony_ci  TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.compile"),
32951cb0ef41Sopenharmony_ci               "V8.StreamingFinalization.Release");
32961cb0ef41Sopenharmony_ci  streaming_data->Release();
32971cb0ef41Sopenharmony_ci  return maybe_result;
32981cb0ef41Sopenharmony_ci}  // namespace internal
32991cb0ef41Sopenharmony_ci
33001cb0ef41Sopenharmony_ci// static
33011cb0ef41Sopenharmony_ciHandle<SharedFunctionInfo> Compiler::GetSharedFunctionInfoForWebSnapshot(
33021cb0ef41Sopenharmony_ci    Isolate* isolate, Handle<String> source,
33031cb0ef41Sopenharmony_ci    MaybeHandle<Object> maybe_script_name) {
33041cb0ef41Sopenharmony_ci  // This script won't hold the functions created from the web snapshot;
33051cb0ef41Sopenharmony_ci  // reserving space only for the top-level SharedFunctionInfo is enough.
33061cb0ef41Sopenharmony_ci  Handle<WeakFixedArray> shared_function_infos =
33071cb0ef41Sopenharmony_ci      isolate->factory()->NewWeakFixedArray(1, AllocationType::kOld);
33081cb0ef41Sopenharmony_ci  Handle<Script> script = isolate->factory()->NewScript(source);
33091cb0ef41Sopenharmony_ci  script->set_type(Script::TYPE_WEB_SNAPSHOT);
33101cb0ef41Sopenharmony_ci  script->set_shared_function_infos(*shared_function_infos);
33111cb0ef41Sopenharmony_ci  Handle<Object> script_name;
33121cb0ef41Sopenharmony_ci  if (maybe_script_name.ToHandle(&script_name) && script_name->IsString()) {
33131cb0ef41Sopenharmony_ci    script->set_name(String::cast(*script_name));
33141cb0ef41Sopenharmony_ci  } else {
33151cb0ef41Sopenharmony_ci    script->set_name(*isolate->factory()->empty_string());
33161cb0ef41Sopenharmony_ci  }
33171cb0ef41Sopenharmony_ci
33181cb0ef41Sopenharmony_ci  Handle<SharedFunctionInfo> shared =
33191cb0ef41Sopenharmony_ci      isolate->factory()->NewSharedFunctionInfoForWebSnapshot();
33201cb0ef41Sopenharmony_ci  shared->SetScript(isolate->factory()->read_only_roots(), *script, 0, false);
33211cb0ef41Sopenharmony_ci  return shared;
33221cb0ef41Sopenharmony_ci}
33231cb0ef41Sopenharmony_ci
33241cb0ef41Sopenharmony_ci// static
33251cb0ef41Sopenharmony_citemplate <typename IsolateT>
33261cb0ef41Sopenharmony_ciHandle<SharedFunctionInfo> Compiler::GetSharedFunctionInfo(
33271cb0ef41Sopenharmony_ci    FunctionLiteral* literal, Handle<Script> script, IsolateT* isolate) {
33281cb0ef41Sopenharmony_ci  // Precondition: code has been parsed and scopes have been analyzed.
33291cb0ef41Sopenharmony_ci  MaybeHandle<SharedFunctionInfo> maybe_existing;
33301cb0ef41Sopenharmony_ci
33311cb0ef41Sopenharmony_ci  // Find any previously allocated shared function info for the given literal.
33321cb0ef41Sopenharmony_ci  maybe_existing = Script::FindSharedFunctionInfo(script, isolate, literal);
33331cb0ef41Sopenharmony_ci
33341cb0ef41Sopenharmony_ci  // If we found an existing shared function info, return it.
33351cb0ef41Sopenharmony_ci  Handle<SharedFunctionInfo> existing;
33361cb0ef41Sopenharmony_ci  if (maybe_existing.ToHandle(&existing)) {
33371cb0ef41Sopenharmony_ci    // If the function has been uncompiled (bytecode flushed) it will have lost
33381cb0ef41Sopenharmony_ci    // any preparsed data. If we produced preparsed data during this compile for
33391cb0ef41Sopenharmony_ci    // this function, replace the uncompiled data with one that includes it.
33401cb0ef41Sopenharmony_ci    if (literal->produced_preparse_data() != nullptr &&
33411cb0ef41Sopenharmony_ci        existing->HasUncompiledDataWithoutPreparseData()) {
33421cb0ef41Sopenharmony_ci      Handle<UncompiledData> existing_uncompiled_data =
33431cb0ef41Sopenharmony_ci          handle(existing->uncompiled_data(), isolate);
33441cb0ef41Sopenharmony_ci      DCHECK_EQ(literal->start_position(),
33451cb0ef41Sopenharmony_ci                existing_uncompiled_data->start_position());
33461cb0ef41Sopenharmony_ci      DCHECK_EQ(literal->end_position(),
33471cb0ef41Sopenharmony_ci                existing_uncompiled_data->end_position());
33481cb0ef41Sopenharmony_ci      // Use existing uncompiled data's inferred name as it may be more
33491cb0ef41Sopenharmony_ci      // accurate than the literal we preparsed.
33501cb0ef41Sopenharmony_ci      Handle<String> inferred_name =
33511cb0ef41Sopenharmony_ci          handle(existing_uncompiled_data->inferred_name(), isolate);
33521cb0ef41Sopenharmony_ci      Handle<PreparseData> preparse_data =
33531cb0ef41Sopenharmony_ci          literal->produced_preparse_data()->Serialize(isolate);
33541cb0ef41Sopenharmony_ci      Handle<UncompiledData> new_uncompiled_data =
33551cb0ef41Sopenharmony_ci          isolate->factory()->NewUncompiledDataWithPreparseData(
33561cb0ef41Sopenharmony_ci              inferred_name, existing_uncompiled_data->start_position(),
33571cb0ef41Sopenharmony_ci              existing_uncompiled_data->end_position(), preparse_data);
33581cb0ef41Sopenharmony_ci      existing->set_uncompiled_data(*new_uncompiled_data);
33591cb0ef41Sopenharmony_ci    }
33601cb0ef41Sopenharmony_ci    return existing;
33611cb0ef41Sopenharmony_ci  }
33621cb0ef41Sopenharmony_ci
33631cb0ef41Sopenharmony_ci  // Allocate a shared function info object which will be compiled lazily.
33641cb0ef41Sopenharmony_ci  Handle<SharedFunctionInfo> result =
33651cb0ef41Sopenharmony_ci      isolate->factory()->NewSharedFunctionInfoForLiteral(literal, script,
33661cb0ef41Sopenharmony_ci                                                          false);
33671cb0ef41Sopenharmony_ci  return result;
33681cb0ef41Sopenharmony_ci}
33691cb0ef41Sopenharmony_ci
33701cb0ef41Sopenharmony_citemplate Handle<SharedFunctionInfo> Compiler::GetSharedFunctionInfo(
33711cb0ef41Sopenharmony_ci    FunctionLiteral* literal, Handle<Script> script, Isolate* isolate);
33721cb0ef41Sopenharmony_citemplate Handle<SharedFunctionInfo> Compiler::GetSharedFunctionInfo(
33731cb0ef41Sopenharmony_ci    FunctionLiteral* literal, Handle<Script> script, LocalIsolate* isolate);
33741cb0ef41Sopenharmony_ci
33751cb0ef41Sopenharmony_ci// static
33761cb0ef41Sopenharmony_ciMaybeHandle<CodeT> Compiler::CompileOptimizedOSR(Isolate* isolate,
33771cb0ef41Sopenharmony_ci                                                 Handle<JSFunction> function,
33781cb0ef41Sopenharmony_ci                                                 BytecodeOffset osr_offset,
33791cb0ef41Sopenharmony_ci                                                 UnoptimizedFrame* frame,
33801cb0ef41Sopenharmony_ci                                                 ConcurrencyMode mode) {
33811cb0ef41Sopenharmony_ci  DCHECK(IsOSR(osr_offset));
33821cb0ef41Sopenharmony_ci  DCHECK_NOT_NULL(frame);
33831cb0ef41Sopenharmony_ci
33841cb0ef41Sopenharmony_ci  if (V8_UNLIKELY(isolate->serializer_enabled())) return {};
33851cb0ef41Sopenharmony_ci  if (V8_UNLIKELY(function->shared().optimization_disabled())) return {};
33861cb0ef41Sopenharmony_ci
33871cb0ef41Sopenharmony_ci  // TODO(chromium:1031479): Currently, OSR triggering mechanism is tied to the
33881cb0ef41Sopenharmony_ci  // bytecode array. So, it might be possible to mark closure in one native
33891cb0ef41Sopenharmony_ci  // context and optimize a closure from a different native context. So check if
33901cb0ef41Sopenharmony_ci  // there is a feedback vector before OSRing. We don't expect this to happen
33911cb0ef41Sopenharmony_ci  // often.
33921cb0ef41Sopenharmony_ci  if (V8_UNLIKELY(!function->has_feedback_vector())) return {};
33931cb0ef41Sopenharmony_ci
33941cb0ef41Sopenharmony_ci  // One OSR job per function at a time.
33951cb0ef41Sopenharmony_ci  if (IsInProgress(function->osr_tiering_state())) {
33961cb0ef41Sopenharmony_ci    return {};
33971cb0ef41Sopenharmony_ci  }
33981cb0ef41Sopenharmony_ci
33991cb0ef41Sopenharmony_ci  // -- Alright, decided to proceed. --
34001cb0ef41Sopenharmony_ci
34011cb0ef41Sopenharmony_ci  // Disarm all back edges, i.e. reset the OSR urgency and install target.
34021cb0ef41Sopenharmony_ci  //
34031cb0ef41Sopenharmony_ci  // Note that the bytecode array active on the stack might be different from
34041cb0ef41Sopenharmony_ci  // the one installed on the function (e.g. patched by debugger). This however
34051cb0ef41Sopenharmony_ci  // is fine because we guarantee the layout to be in sync, hence any
34061cb0ef41Sopenharmony_ci  // BytecodeOffset representing the entry point will be valid for any copy of
34071cb0ef41Sopenharmony_ci  // the bytecode.
34081cb0ef41Sopenharmony_ci  Handle<BytecodeArray> bytecode(frame->GetBytecodeArray(), isolate);
34091cb0ef41Sopenharmony_ci  bytecode->reset_osr_urgency_and_install_target();
34101cb0ef41Sopenharmony_ci
34111cb0ef41Sopenharmony_ci  CompilerTracer::TraceOptimizeOSR(isolate, function, osr_offset, mode);
34121cb0ef41Sopenharmony_ci  MaybeHandle<CodeT> result = GetOrCompileOptimized(
34131cb0ef41Sopenharmony_ci      isolate, function, mode, CodeKind::TURBOFAN, osr_offset, frame);
34141cb0ef41Sopenharmony_ci
34151cb0ef41Sopenharmony_ci  if (result.is_null()) {
34161cb0ef41Sopenharmony_ci    CompilerTracer::TraceOptimizeOSRUnavailable(isolate, function, osr_offset,
34171cb0ef41Sopenharmony_ci                                                mode);
34181cb0ef41Sopenharmony_ci  }
34191cb0ef41Sopenharmony_ci
34201cb0ef41Sopenharmony_ci  return result;
34211cb0ef41Sopenharmony_ci}
34221cb0ef41Sopenharmony_ci
34231cb0ef41Sopenharmony_ci// static
34241cb0ef41Sopenharmony_civoid Compiler::DisposeTurbofanCompilationJob(TurbofanCompilationJob* job,
34251cb0ef41Sopenharmony_ci                                             bool restore_function_code) {
34261cb0ef41Sopenharmony_ci  Handle<JSFunction> function = job->compilation_info()->closure();
34271cb0ef41Sopenharmony_ci  ResetTieringState(*function, job->compilation_info()->osr_offset());
34281cb0ef41Sopenharmony_ci  if (restore_function_code) {
34291cb0ef41Sopenharmony_ci    function->set_code(function->shared().GetCode(), kReleaseStore);
34301cb0ef41Sopenharmony_ci  }
34311cb0ef41Sopenharmony_ci}
34321cb0ef41Sopenharmony_ci
34331cb0ef41Sopenharmony_ci// static
34341cb0ef41Sopenharmony_cibool Compiler::FinalizeTurbofanCompilationJob(TurbofanCompilationJob* job,
34351cb0ef41Sopenharmony_ci                                              Isolate* isolate) {
34361cb0ef41Sopenharmony_ci  VMState<COMPILER> state(isolate);
34371cb0ef41Sopenharmony_ci  OptimizedCompilationInfo* compilation_info = job->compilation_info();
34381cb0ef41Sopenharmony_ci
34391cb0ef41Sopenharmony_ci  TimerEventScope<TimerEventRecompileSynchronous> timer(isolate);
34401cb0ef41Sopenharmony_ci  RCS_SCOPE(isolate, RuntimeCallCounterId::kOptimizeConcurrentFinalize);
34411cb0ef41Sopenharmony_ci  TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.compile"),
34421cb0ef41Sopenharmony_ci               "V8.OptimizeConcurrentFinalize");
34431cb0ef41Sopenharmony_ci
34441cb0ef41Sopenharmony_ci  Handle<JSFunction> function = compilation_info->closure();
34451cb0ef41Sopenharmony_ci  Handle<SharedFunctionInfo> shared = compilation_info->shared_info();
34461cb0ef41Sopenharmony_ci
34471cb0ef41Sopenharmony_ci  const bool use_result = !compilation_info->discard_result_for_testing();
34481cb0ef41Sopenharmony_ci  const BytecodeOffset osr_offset = compilation_info->osr_offset();
34491cb0ef41Sopenharmony_ci
34501cb0ef41Sopenharmony_ci  if (V8_LIKELY(use_result)) {
34511cb0ef41Sopenharmony_ci    ResetProfilerTicks(*function, osr_offset);
34521cb0ef41Sopenharmony_ci  }
34531cb0ef41Sopenharmony_ci
34541cb0ef41Sopenharmony_ci  DCHECK(!shared->HasBreakInfo());
34551cb0ef41Sopenharmony_ci
34561cb0ef41Sopenharmony_ci  // 1) Optimization on the concurrent thread may have failed.
34571cb0ef41Sopenharmony_ci  // 2) The function may have already been optimized by OSR.  Simply continue.
34581cb0ef41Sopenharmony_ci  //    Except when OSR already disabled optimization for some reason.
34591cb0ef41Sopenharmony_ci  // 3) The code may have already been invalidated due to dependency change.
34601cb0ef41Sopenharmony_ci  // 4) Code generation may have failed.
34611cb0ef41Sopenharmony_ci  if (job->state() == CompilationJob::State::kReadyToFinalize) {
34621cb0ef41Sopenharmony_ci    if (shared->optimization_disabled()) {
34631cb0ef41Sopenharmony_ci      job->RetryOptimization(BailoutReason::kOptimizationDisabled);
34641cb0ef41Sopenharmony_ci    } else if (job->FinalizeJob(isolate) == CompilationJob::SUCCEEDED) {
34651cb0ef41Sopenharmony_ci      job->RecordCompilationStats(ConcurrencyMode::kConcurrent, isolate);
34661cb0ef41Sopenharmony_ci      job->RecordFunctionCompilation(CodeEventListener::LAZY_COMPILE_TAG,
34671cb0ef41Sopenharmony_ci                                     isolate);
34681cb0ef41Sopenharmony_ci      if (V8_LIKELY(use_result)) {
34691cb0ef41Sopenharmony_ci        ResetTieringState(*function, osr_offset);
34701cb0ef41Sopenharmony_ci        OptimizedCodeCache::Insert(compilation_info);
34711cb0ef41Sopenharmony_ci        CompilerTracer::TraceCompletedJob(isolate, compilation_info);
34721cb0ef41Sopenharmony_ci        if (IsOSR(osr_offset)) {
34731cb0ef41Sopenharmony_ci          if (FLAG_trace_osr) {
34741cb0ef41Sopenharmony_ci            PrintF(CodeTracer::Scope{isolate->GetCodeTracer()}.file(),
34751cb0ef41Sopenharmony_ci                   "[OSR - requesting install. function: %s, osr offset: %d]\n",
34761cb0ef41Sopenharmony_ci                   function->DebugNameCStr().get(), osr_offset.ToInt());
34771cb0ef41Sopenharmony_ci          }
34781cb0ef41Sopenharmony_ci          shared->GetBytecodeArray(isolate).set_osr_install_target(osr_offset);
34791cb0ef41Sopenharmony_ci        } else {
34801cb0ef41Sopenharmony_ci          function->set_code(*compilation_info->code(), kReleaseStore);
34811cb0ef41Sopenharmony_ci        }
34821cb0ef41Sopenharmony_ci      }
34831cb0ef41Sopenharmony_ci      return CompilationJob::SUCCEEDED;
34841cb0ef41Sopenharmony_ci    }
34851cb0ef41Sopenharmony_ci  }
34861cb0ef41Sopenharmony_ci
34871cb0ef41Sopenharmony_ci  DCHECK_EQ(job->state(), CompilationJob::State::kFailed);
34881cb0ef41Sopenharmony_ci  CompilerTracer::TraceAbortedJob(isolate, compilation_info);
34891cb0ef41Sopenharmony_ci  if (V8_LIKELY(use_result)) {
34901cb0ef41Sopenharmony_ci    ResetTieringState(*function, osr_offset);
34911cb0ef41Sopenharmony_ci    if (!IsOSR(osr_offset)) {
34921cb0ef41Sopenharmony_ci      function->set_code(shared->GetCode(), kReleaseStore);
34931cb0ef41Sopenharmony_ci    }
34941cb0ef41Sopenharmony_ci  }
34951cb0ef41Sopenharmony_ci  return CompilationJob::FAILED;
34961cb0ef41Sopenharmony_ci}
34971cb0ef41Sopenharmony_ci
34981cb0ef41Sopenharmony_ci// static
34991cb0ef41Sopenharmony_cibool Compiler::FinalizeMaglevCompilationJob(maglev::MaglevCompilationJob* job,
35001cb0ef41Sopenharmony_ci                                            Isolate* isolate) {
35011cb0ef41Sopenharmony_ci#ifdef V8_ENABLE_MAGLEV
35021cb0ef41Sopenharmony_ci  VMState<COMPILER> state(isolate);
35031cb0ef41Sopenharmony_ci  RecordMaglevFunctionCompilation(isolate, job->function());
35041cb0ef41Sopenharmony_ci#endif
35051cb0ef41Sopenharmony_ci  return CompilationJob::SUCCEEDED;
35061cb0ef41Sopenharmony_ci}
35071cb0ef41Sopenharmony_ci
35081cb0ef41Sopenharmony_ci// static
35091cb0ef41Sopenharmony_civoid Compiler::PostInstantiation(Handle<JSFunction> function) {
35101cb0ef41Sopenharmony_ci  Isolate* isolate = function->GetIsolate();
35111cb0ef41Sopenharmony_ci  Handle<SharedFunctionInfo> shared(function->shared(), isolate);
35121cb0ef41Sopenharmony_ci  IsCompiledScope is_compiled_scope(shared->is_compiled_scope(isolate));
35131cb0ef41Sopenharmony_ci
35141cb0ef41Sopenharmony_ci  // If code is compiled to bytecode (i.e., isn't asm.js), then allocate a
35151cb0ef41Sopenharmony_ci  // feedback and check for optimized code.
35161cb0ef41Sopenharmony_ci  if (is_compiled_scope.is_compiled() && shared->HasBytecodeArray()) {
35171cb0ef41Sopenharmony_ci    // Don't reset budget if there is a closure feedback cell array already. We
35181cb0ef41Sopenharmony_ci    // are just creating a new closure that shares the same feedback cell.
35191cb0ef41Sopenharmony_ci    JSFunction::InitializeFeedbackCell(function, &is_compiled_scope, false);
35201cb0ef41Sopenharmony_ci
35211cb0ef41Sopenharmony_ci    if (function->has_feedback_vector()) {
35221cb0ef41Sopenharmony_ci      // Evict any deoptimized code on feedback vector. We need to do this after
35231cb0ef41Sopenharmony_ci      // creating the closure, since any heap allocations could trigger a GC and
35241cb0ef41Sopenharmony_ci      // deoptimized the code on the feedback vector. So check for any
35251cb0ef41Sopenharmony_ci      // deoptimized code just before installing it on the funciton.
35261cb0ef41Sopenharmony_ci      function->feedback_vector().EvictOptimizedCodeMarkedForDeoptimization(
35271cb0ef41Sopenharmony_ci          *shared, "new function from shared function info");
35281cb0ef41Sopenharmony_ci      CodeT code = function->feedback_vector().optimized_code();
35291cb0ef41Sopenharmony_ci      if (!code.is_null()) {
35301cb0ef41Sopenharmony_ci        // Caching of optimized code enabled and optimized code found.
35311cb0ef41Sopenharmony_ci        DCHECK(!code.marked_for_deoptimization());
35321cb0ef41Sopenharmony_ci        DCHECK(function->shared().is_compiled());
35331cb0ef41Sopenharmony_ci
35341cb0ef41Sopenharmony_ci        // We don't need a release store because the optimized code was
35351cb0ef41Sopenharmony_ci        // stored with release semantics into the vector
35361cb0ef41Sopenharmony_ci        STATIC_ASSERT(
35371cb0ef41Sopenharmony_ci            FeedbackVector::kFeedbackVectorMaybeOptimizedCodeIsStoreRelease);
35381cb0ef41Sopenharmony_ci        function->set_code(code);
35391cb0ef41Sopenharmony_ci      }
35401cb0ef41Sopenharmony_ci    }
35411cb0ef41Sopenharmony_ci
35421cb0ef41Sopenharmony_ci    if (FLAG_always_opt && shared->allows_lazy_compilation() &&
35431cb0ef41Sopenharmony_ci        !shared->optimization_disabled() &&
35441cb0ef41Sopenharmony_ci        !function->HasAvailableOptimizedCode()) {
35451cb0ef41Sopenharmony_ci      CompilerTracer::TraceMarkForAlwaysOpt(isolate, function);
35461cb0ef41Sopenharmony_ci      JSFunction::EnsureFeedbackVector(isolate, function, &is_compiled_scope);
35471cb0ef41Sopenharmony_ci      function->MarkForOptimization(isolate, CodeKind::TURBOFAN,
35481cb0ef41Sopenharmony_ci                                    ConcurrencyMode::kSynchronous);
35491cb0ef41Sopenharmony_ci    }
35501cb0ef41Sopenharmony_ci  }
35511cb0ef41Sopenharmony_ci
35521cb0ef41Sopenharmony_ci  if (shared->is_toplevel() || shared->is_wrapped()) {
35531cb0ef41Sopenharmony_ci    // If it's a top-level script, report compilation to the debugger.
35541cb0ef41Sopenharmony_ci    Handle<Script> script(Script::cast(shared->script()), isolate);
35551cb0ef41Sopenharmony_ci    isolate->debug()->OnAfterCompile(script);
35561cb0ef41Sopenharmony_ci  }
35571cb0ef41Sopenharmony_ci}
35581cb0ef41Sopenharmony_ci
35591cb0ef41Sopenharmony_ci// ----------------------------------------------------------------------------
35601cb0ef41Sopenharmony_ci// Implementation of ScriptStreamingData
35611cb0ef41Sopenharmony_ci
35621cb0ef41Sopenharmony_ciScriptStreamingData::ScriptStreamingData(
35631cb0ef41Sopenharmony_ci    std::unique_ptr<ScriptCompiler::ExternalSourceStream> source_stream,
35641cb0ef41Sopenharmony_ci    ScriptCompiler::StreamedSource::Encoding encoding)
35651cb0ef41Sopenharmony_ci    : source_stream(std::move(source_stream)), encoding(encoding) {}
35661cb0ef41Sopenharmony_ci
35671cb0ef41Sopenharmony_ciScriptStreamingData::~ScriptStreamingData() = default;
35681cb0ef41Sopenharmony_ci
35691cb0ef41Sopenharmony_civoid ScriptStreamingData::Release() { task.reset(); }
35701cb0ef41Sopenharmony_ci
35711cb0ef41Sopenharmony_ci}  // namespace internal
35721cb0ef41Sopenharmony_ci}  // namespace v8
3573