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