11cb0ef41Sopenharmony_ci// Copyright 2014 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/asmjs/asm-js.h" 61cb0ef41Sopenharmony_ci#include "src/baseline/baseline.h" 71cb0ef41Sopenharmony_ci#include "src/codegen/compilation-cache.h" 81cb0ef41Sopenharmony_ci#include "src/codegen/compiler.h" 91cb0ef41Sopenharmony_ci#include "src/codegen/optimized-compilation-info.h" 101cb0ef41Sopenharmony_ci#include "src/common/assert-scope.h" 111cb0ef41Sopenharmony_ci#include "src/common/globals.h" 121cb0ef41Sopenharmony_ci#include "src/common/message-template.h" 131cb0ef41Sopenharmony_ci#include "src/compiler-dispatcher/optimizing-compile-dispatcher.h" 141cb0ef41Sopenharmony_ci#include "src/compiler/pipeline.h" 151cb0ef41Sopenharmony_ci#include "src/deoptimizer/deoptimizer.h" 161cb0ef41Sopenharmony_ci#include "src/execution/arguments-inl.h" 171cb0ef41Sopenharmony_ci#include "src/execution/frames-inl.h" 181cb0ef41Sopenharmony_ci#include "src/execution/isolate-inl.h" 191cb0ef41Sopenharmony_ci#include "src/execution/v8threads.h" 201cb0ef41Sopenharmony_ci#include "src/execution/vm-state-inl.h" 211cb0ef41Sopenharmony_ci#include "src/heap/parked-scope.h" 221cb0ef41Sopenharmony_ci#include "src/objects/js-array-buffer-inl.h" 231cb0ef41Sopenharmony_ci#include "src/objects/js-array-inl.h" 241cb0ef41Sopenharmony_ci#include "src/objects/shared-function-info.h" 251cb0ef41Sopenharmony_ci#include "src/runtime/runtime-utils.h" 261cb0ef41Sopenharmony_ci 271cb0ef41Sopenharmony_cinamespace v8 { 281cb0ef41Sopenharmony_cinamespace internal { 291cb0ef41Sopenharmony_ci 301cb0ef41Sopenharmony_cinamespace { 311cb0ef41Sopenharmony_ci 321cb0ef41Sopenharmony_ciObject CompileOptimized(Isolate* isolate, Handle<JSFunction> function, 331cb0ef41Sopenharmony_ci CodeKind target_kind, ConcurrencyMode mode) { 341cb0ef41Sopenharmony_ci // As a pre- and post-condition of CompileOptimized, the function *must* be 351cb0ef41Sopenharmony_ci // compiled, i.e. the installed Code object must not be CompileLazy. 361cb0ef41Sopenharmony_ci IsCompiledScope is_compiled_scope(function->shared(), isolate); 371cb0ef41Sopenharmony_ci DCHECK(is_compiled_scope.is_compiled()); 381cb0ef41Sopenharmony_ci 391cb0ef41Sopenharmony_ci StackLimitCheck check(isolate); 401cb0ef41Sopenharmony_ci // Concurrent optimization runs on another thread, thus no additional gap. 411cb0ef41Sopenharmony_ci const int gap = 421cb0ef41Sopenharmony_ci IsConcurrent(mode) ? 0 : kStackSpaceRequiredForCompilation * KB; 431cb0ef41Sopenharmony_ci if (check.JsHasOverflowed(gap)) return isolate->StackOverflow(); 441cb0ef41Sopenharmony_ci 451cb0ef41Sopenharmony_ci Compiler::CompileOptimized(isolate, function, mode, target_kind); 461cb0ef41Sopenharmony_ci 471cb0ef41Sopenharmony_ci DCHECK(function->is_compiled()); 481cb0ef41Sopenharmony_ci return function->code(); 491cb0ef41Sopenharmony_ci} 501cb0ef41Sopenharmony_ci 511cb0ef41Sopenharmony_ci} // namespace 521cb0ef41Sopenharmony_ci 531cb0ef41Sopenharmony_ciRUNTIME_FUNCTION(Runtime_CompileLazy) { 541cb0ef41Sopenharmony_ci HandleScope scope(isolate); 551cb0ef41Sopenharmony_ci DCHECK_EQ(1, args.length()); 561cb0ef41Sopenharmony_ci Handle<JSFunction> function = args.at<JSFunction>(0); 571cb0ef41Sopenharmony_ci 581cb0ef41Sopenharmony_ci Handle<SharedFunctionInfo> sfi(function->shared(), isolate); 591cb0ef41Sopenharmony_ci 601cb0ef41Sopenharmony_ci#ifdef DEBUG 611cb0ef41Sopenharmony_ci if (FLAG_trace_lazy && !sfi->is_compiled()) { 621cb0ef41Sopenharmony_ci PrintF("[unoptimized: %s]\n", function->DebugNameCStr().get()); 631cb0ef41Sopenharmony_ci } 641cb0ef41Sopenharmony_ci#endif 651cb0ef41Sopenharmony_ci 661cb0ef41Sopenharmony_ci StackLimitCheck check(isolate); 671cb0ef41Sopenharmony_ci if (check.JsHasOverflowed(kStackSpaceRequiredForCompilation * KB)) { 681cb0ef41Sopenharmony_ci return isolate->StackOverflow(); 691cb0ef41Sopenharmony_ci } 701cb0ef41Sopenharmony_ci IsCompiledScope is_compiled_scope; 711cb0ef41Sopenharmony_ci if (!Compiler::Compile(isolate, function, Compiler::KEEP_EXCEPTION, 721cb0ef41Sopenharmony_ci &is_compiled_scope)) { 731cb0ef41Sopenharmony_ci return ReadOnlyRoots(isolate).exception(); 741cb0ef41Sopenharmony_ci } 751cb0ef41Sopenharmony_ci DCHECK(function->is_compiled()); 761cb0ef41Sopenharmony_ci return function->code(); 771cb0ef41Sopenharmony_ci} 781cb0ef41Sopenharmony_ci 791cb0ef41Sopenharmony_ciRUNTIME_FUNCTION(Runtime_InstallBaselineCode) { 801cb0ef41Sopenharmony_ci HandleScope scope(isolate); 811cb0ef41Sopenharmony_ci DCHECK_EQ(1, args.length()); 821cb0ef41Sopenharmony_ci Handle<JSFunction> function = args.at<JSFunction>(0); 831cb0ef41Sopenharmony_ci Handle<SharedFunctionInfo> sfi(function->shared(), isolate); 841cb0ef41Sopenharmony_ci DCHECK(sfi->HasBaselineCode()); 851cb0ef41Sopenharmony_ci IsCompiledScope is_compiled_scope(*sfi, isolate); 861cb0ef41Sopenharmony_ci DCHECK(!function->HasAvailableOptimizedCode()); 871cb0ef41Sopenharmony_ci DCHECK(!function->has_feedback_vector()); 881cb0ef41Sopenharmony_ci JSFunction::CreateAndAttachFeedbackVector(isolate, function, 891cb0ef41Sopenharmony_ci &is_compiled_scope); 901cb0ef41Sopenharmony_ci CodeT baseline_code = sfi->baseline_code(kAcquireLoad); 911cb0ef41Sopenharmony_ci function->set_code(baseline_code); 921cb0ef41Sopenharmony_ci return baseline_code; 931cb0ef41Sopenharmony_ci} 941cb0ef41Sopenharmony_ci 951cb0ef41Sopenharmony_ciRUNTIME_FUNCTION(Runtime_CompileMaglev_Concurrent) { 961cb0ef41Sopenharmony_ci HandleScope scope(isolate); 971cb0ef41Sopenharmony_ci DCHECK_EQ(1, args.length()); 981cb0ef41Sopenharmony_ci Handle<JSFunction> function = args.at<JSFunction>(0); 991cb0ef41Sopenharmony_ci return CompileOptimized(isolate, function, CodeKind::MAGLEV, 1001cb0ef41Sopenharmony_ci ConcurrencyMode::kConcurrent); 1011cb0ef41Sopenharmony_ci} 1021cb0ef41Sopenharmony_ci 1031cb0ef41Sopenharmony_ciRUNTIME_FUNCTION(Runtime_CompileMaglev_Synchronous) { 1041cb0ef41Sopenharmony_ci HandleScope scope(isolate); 1051cb0ef41Sopenharmony_ci DCHECK_EQ(1, args.length()); 1061cb0ef41Sopenharmony_ci Handle<JSFunction> function = args.at<JSFunction>(0); 1071cb0ef41Sopenharmony_ci return CompileOptimized(isolate, function, CodeKind::MAGLEV, 1081cb0ef41Sopenharmony_ci ConcurrencyMode::kSynchronous); 1091cb0ef41Sopenharmony_ci} 1101cb0ef41Sopenharmony_ci 1111cb0ef41Sopenharmony_ciRUNTIME_FUNCTION(Runtime_CompileTurbofan_Concurrent) { 1121cb0ef41Sopenharmony_ci HandleScope scope(isolate); 1131cb0ef41Sopenharmony_ci DCHECK_EQ(1, args.length()); 1141cb0ef41Sopenharmony_ci Handle<JSFunction> function = args.at<JSFunction>(0); 1151cb0ef41Sopenharmony_ci return CompileOptimized(isolate, function, CodeKind::TURBOFAN, 1161cb0ef41Sopenharmony_ci ConcurrencyMode::kConcurrent); 1171cb0ef41Sopenharmony_ci} 1181cb0ef41Sopenharmony_ci 1191cb0ef41Sopenharmony_ciRUNTIME_FUNCTION(Runtime_CompileTurbofan_Synchronous) { 1201cb0ef41Sopenharmony_ci HandleScope scope(isolate); 1211cb0ef41Sopenharmony_ci DCHECK_EQ(1, args.length()); 1221cb0ef41Sopenharmony_ci Handle<JSFunction> function = args.at<JSFunction>(0); 1231cb0ef41Sopenharmony_ci return CompileOptimized(isolate, function, CodeKind::TURBOFAN, 1241cb0ef41Sopenharmony_ci ConcurrencyMode::kSynchronous); 1251cb0ef41Sopenharmony_ci} 1261cb0ef41Sopenharmony_ci 1271cb0ef41Sopenharmony_ciRUNTIME_FUNCTION(Runtime_HealOptimizedCodeSlot) { 1281cb0ef41Sopenharmony_ci SealHandleScope scope(isolate); 1291cb0ef41Sopenharmony_ci DCHECK_EQ(1, args.length()); 1301cb0ef41Sopenharmony_ci Handle<JSFunction> function = args.at<JSFunction>(0); 1311cb0ef41Sopenharmony_ci 1321cb0ef41Sopenharmony_ci DCHECK(function->shared().is_compiled()); 1331cb0ef41Sopenharmony_ci 1341cb0ef41Sopenharmony_ci function->feedback_vector().EvictOptimizedCodeMarkedForDeoptimization( 1351cb0ef41Sopenharmony_ci function->shared(), "Runtime_HealOptimizedCodeSlot"); 1361cb0ef41Sopenharmony_ci return function->code(); 1371cb0ef41Sopenharmony_ci} 1381cb0ef41Sopenharmony_ci 1391cb0ef41Sopenharmony_ciRUNTIME_FUNCTION(Runtime_InstantiateAsmJs) { 1401cb0ef41Sopenharmony_ci HandleScope scope(isolate); 1411cb0ef41Sopenharmony_ci DCHECK_EQ(args.length(), 4); 1421cb0ef41Sopenharmony_ci Handle<JSFunction> function = args.at<JSFunction>(0); 1431cb0ef41Sopenharmony_ci 1441cb0ef41Sopenharmony_ci Handle<JSReceiver> stdlib; 1451cb0ef41Sopenharmony_ci if (args[1].IsJSReceiver()) { 1461cb0ef41Sopenharmony_ci stdlib = args.at<JSReceiver>(1); 1471cb0ef41Sopenharmony_ci } 1481cb0ef41Sopenharmony_ci Handle<JSReceiver> foreign; 1491cb0ef41Sopenharmony_ci if (args[2].IsJSReceiver()) { 1501cb0ef41Sopenharmony_ci foreign = args.at<JSReceiver>(2); 1511cb0ef41Sopenharmony_ci } 1521cb0ef41Sopenharmony_ci Handle<JSArrayBuffer> memory; 1531cb0ef41Sopenharmony_ci if (args[3].IsJSArrayBuffer()) { 1541cb0ef41Sopenharmony_ci memory = args.at<JSArrayBuffer>(3); 1551cb0ef41Sopenharmony_ci } 1561cb0ef41Sopenharmony_ci Handle<SharedFunctionInfo> shared(function->shared(), isolate); 1571cb0ef41Sopenharmony_ci#if V8_ENABLE_WEBASSEMBLY 1581cb0ef41Sopenharmony_ci if (shared->HasAsmWasmData()) { 1591cb0ef41Sopenharmony_ci Handle<AsmWasmData> data(shared->asm_wasm_data(), isolate); 1601cb0ef41Sopenharmony_ci MaybeHandle<Object> result = AsmJs::InstantiateAsmWasm( 1611cb0ef41Sopenharmony_ci isolate, shared, data, stdlib, foreign, memory); 1621cb0ef41Sopenharmony_ci if (!result.is_null()) return *result.ToHandleChecked(); 1631cb0ef41Sopenharmony_ci // Remove wasm data, mark as broken for asm->wasm, replace function code 1641cb0ef41Sopenharmony_ci // with UncompiledData, and return a smi 0 to indicate failure. 1651cb0ef41Sopenharmony_ci SharedFunctionInfo::DiscardCompiled(isolate, shared); 1661cb0ef41Sopenharmony_ci } 1671cb0ef41Sopenharmony_ci shared->set_is_asm_wasm_broken(true); 1681cb0ef41Sopenharmony_ci#endif 1691cb0ef41Sopenharmony_ci DCHECK_EQ(function->code(), *BUILTIN_CODE(isolate, InstantiateAsmJs)); 1701cb0ef41Sopenharmony_ci function->set_code(*BUILTIN_CODE(isolate, CompileLazy)); 1711cb0ef41Sopenharmony_ci DCHECK(!isolate->has_pending_exception()); 1721cb0ef41Sopenharmony_ci return Smi::zero(); 1731cb0ef41Sopenharmony_ci} 1741cb0ef41Sopenharmony_ci 1751cb0ef41Sopenharmony_ciRUNTIME_FUNCTION(Runtime_NotifyDeoptimized) { 1761cb0ef41Sopenharmony_ci HandleScope scope(isolate); 1771cb0ef41Sopenharmony_ci DCHECK_EQ(0, args.length()); 1781cb0ef41Sopenharmony_ci Deoptimizer* deoptimizer = Deoptimizer::Grab(isolate); 1791cb0ef41Sopenharmony_ci DCHECK(CodeKindCanDeoptimize(deoptimizer->compiled_code()->kind())); 1801cb0ef41Sopenharmony_ci DCHECK(AllowGarbageCollection::IsAllowed()); 1811cb0ef41Sopenharmony_ci DCHECK(isolate->context().is_null()); 1821cb0ef41Sopenharmony_ci 1831cb0ef41Sopenharmony_ci TimerEventScope<TimerEventDeoptimizeCode> timer(isolate); 1841cb0ef41Sopenharmony_ci TRACE_EVENT0("v8", "V8.DeoptimizeCode"); 1851cb0ef41Sopenharmony_ci Handle<JSFunction> function = deoptimizer->function(); 1861cb0ef41Sopenharmony_ci // For OSR the optimized code isn't installed on the function, so get the 1871cb0ef41Sopenharmony_ci // code object from deoptimizer. 1881cb0ef41Sopenharmony_ci Handle<Code> optimized_code = deoptimizer->compiled_code(); 1891cb0ef41Sopenharmony_ci DeoptimizeKind type = deoptimizer->deopt_kind(); 1901cb0ef41Sopenharmony_ci 1911cb0ef41Sopenharmony_ci // TODO(turbofan): We currently need the native context to materialize 1921cb0ef41Sopenharmony_ci // the arguments object, but only to get to its map. 1931cb0ef41Sopenharmony_ci isolate->set_context(deoptimizer->function()->native_context()); 1941cb0ef41Sopenharmony_ci 1951cb0ef41Sopenharmony_ci // Make sure to materialize objects before causing any allocation. 1961cb0ef41Sopenharmony_ci deoptimizer->MaterializeHeapObjects(); 1971cb0ef41Sopenharmony_ci delete deoptimizer; 1981cb0ef41Sopenharmony_ci 1991cb0ef41Sopenharmony_ci // Ensure the context register is updated for materialized objects. 2001cb0ef41Sopenharmony_ci JavaScriptFrameIterator top_it(isolate); 2011cb0ef41Sopenharmony_ci JavaScriptFrame* top_frame = top_it.frame(); 2021cb0ef41Sopenharmony_ci isolate->set_context(Context::cast(top_frame->context())); 2031cb0ef41Sopenharmony_ci 2041cb0ef41Sopenharmony_ci // Invalidate the underlying optimized code on eager deopts. 2051cb0ef41Sopenharmony_ci if (type == DeoptimizeKind::kEager) { 2061cb0ef41Sopenharmony_ci Deoptimizer::DeoptimizeFunction(*function, *optimized_code); 2071cb0ef41Sopenharmony_ci } 2081cb0ef41Sopenharmony_ci 2091cb0ef41Sopenharmony_ci return ReadOnlyRoots(isolate).undefined_value(); 2101cb0ef41Sopenharmony_ci} 2111cb0ef41Sopenharmony_ci 2121cb0ef41Sopenharmony_ciRUNTIME_FUNCTION(Runtime_ObserveNode) { 2131cb0ef41Sopenharmony_ci // The %ObserveNode intrinsic only tracks the changes to an observed node in 2141cb0ef41Sopenharmony_ci // code compiled by TurboFan. 2151cb0ef41Sopenharmony_ci HandleScope scope(isolate); 2161cb0ef41Sopenharmony_ci DCHECK_EQ(1, args.length()); 2171cb0ef41Sopenharmony_ci Handle<Object> obj = args.at(0); 2181cb0ef41Sopenharmony_ci return *obj; 2191cb0ef41Sopenharmony_ci} 2201cb0ef41Sopenharmony_ci 2211cb0ef41Sopenharmony_ciRUNTIME_FUNCTION(Runtime_VerifyType) { 2221cb0ef41Sopenharmony_ci // %VerifyType has no effect in the interpreter. 2231cb0ef41Sopenharmony_ci HandleScope scope(isolate); 2241cb0ef41Sopenharmony_ci DCHECK_EQ(1, args.length()); 2251cb0ef41Sopenharmony_ci Handle<Object> obj = args.at(0); 2261cb0ef41Sopenharmony_ci return *obj; 2271cb0ef41Sopenharmony_ci} 2281cb0ef41Sopenharmony_ci 2291cb0ef41Sopenharmony_ciRUNTIME_FUNCTION(Runtime_CompileOptimizedOSR) { 2301cb0ef41Sopenharmony_ci HandleScope handle_scope(isolate); 2311cb0ef41Sopenharmony_ci DCHECK_EQ(0, args.length()); 2321cb0ef41Sopenharmony_ci DCHECK(FLAG_use_osr); 2331cb0ef41Sopenharmony_ci 2341cb0ef41Sopenharmony_ci // Determine the frame that triggered the OSR request. 2351cb0ef41Sopenharmony_ci JavaScriptFrameIterator it(isolate); 2361cb0ef41Sopenharmony_ci UnoptimizedFrame* frame = UnoptimizedFrame::cast(it.frame()); 2371cb0ef41Sopenharmony_ci 2381cb0ef41Sopenharmony_ci DCHECK_IMPLIES(frame->is_interpreted(), 2391cb0ef41Sopenharmony_ci frame->LookupCode().is_interpreter_trampoline_builtin()); 2401cb0ef41Sopenharmony_ci DCHECK_IMPLIES(frame->is_baseline(), 2411cb0ef41Sopenharmony_ci frame->LookupCode().kind() == CodeKind::BASELINE); 2421cb0ef41Sopenharmony_ci DCHECK(frame->function().shared().HasBytecodeArray()); 2431cb0ef41Sopenharmony_ci 2441cb0ef41Sopenharmony_ci // Determine the entry point for which this OSR request has been fired. 2451cb0ef41Sopenharmony_ci BytecodeOffset osr_offset = BytecodeOffset(frame->GetBytecodeOffset()); 2461cb0ef41Sopenharmony_ci DCHECK(!osr_offset.IsNone()); 2471cb0ef41Sopenharmony_ci 2481cb0ef41Sopenharmony_ci ConcurrencyMode mode = 2491cb0ef41Sopenharmony_ci V8_LIKELY(isolate->concurrent_recompilation_enabled() && 2501cb0ef41Sopenharmony_ci FLAG_concurrent_osr) 2511cb0ef41Sopenharmony_ci ? ConcurrencyMode::kConcurrent 2521cb0ef41Sopenharmony_ci : ConcurrencyMode::kSynchronous; 2531cb0ef41Sopenharmony_ci 2541cb0ef41Sopenharmony_ci Handle<JSFunction> function(frame->function(), isolate); 2551cb0ef41Sopenharmony_ci if (IsConcurrent(mode)) { 2561cb0ef41Sopenharmony_ci // The synchronous fallback mechanism triggers if we've already got OSR'd 2571cb0ef41Sopenharmony_ci // code for the current function but at a different OSR offset - that may 2581cb0ef41Sopenharmony_ci // indicate we're having trouble hitting the correct JumpLoop for code 2591cb0ef41Sopenharmony_ci // installation. In this case, fall back to synchronous OSR. 2601cb0ef41Sopenharmony_ci base::Optional<BytecodeOffset> cached_osr_offset = 2611cb0ef41Sopenharmony_ci function->native_context().osr_code_cache().FirstOsrOffsetFor( 2621cb0ef41Sopenharmony_ci function->shared()); 2631cb0ef41Sopenharmony_ci if (cached_osr_offset.has_value() && 2641cb0ef41Sopenharmony_ci cached_osr_offset.value() != osr_offset) { 2651cb0ef41Sopenharmony_ci if (V8_UNLIKELY(FLAG_trace_osr)) { 2661cb0ef41Sopenharmony_ci CodeTracer::Scope scope(isolate->GetCodeTracer()); 2671cb0ef41Sopenharmony_ci PrintF( 2681cb0ef41Sopenharmony_ci scope.file(), 2691cb0ef41Sopenharmony_ci "[OSR - falling back to synchronous compilation due to mismatched " 2701cb0ef41Sopenharmony_ci "cached entry. function: %s, requested: %d, cached: %d]\n", 2711cb0ef41Sopenharmony_ci function->DebugNameCStr().get(), osr_offset.ToInt(), 2721cb0ef41Sopenharmony_ci cached_osr_offset.value().ToInt()); 2731cb0ef41Sopenharmony_ci } 2741cb0ef41Sopenharmony_ci mode = ConcurrencyMode::kSynchronous; 2751cb0ef41Sopenharmony_ci } 2761cb0ef41Sopenharmony_ci } 2771cb0ef41Sopenharmony_ci 2781cb0ef41Sopenharmony_ci Handle<CodeT> result; 2791cb0ef41Sopenharmony_ci if (!Compiler::CompileOptimizedOSR(isolate, function, osr_offset, frame, mode) 2801cb0ef41Sopenharmony_ci .ToHandle(&result)) { 2811cb0ef41Sopenharmony_ci // An empty result can mean one of two things: 2821cb0ef41Sopenharmony_ci // 1) we've started a concurrent compilation job - everything is fine. 2831cb0ef41Sopenharmony_ci // 2) synchronous compilation failed for some reason. 2841cb0ef41Sopenharmony_ci 2851cb0ef41Sopenharmony_ci if (!function->HasAttachedOptimizedCode()) { 2861cb0ef41Sopenharmony_ci function->set_code(function->shared().GetCode(), kReleaseStore); 2871cb0ef41Sopenharmony_ci } 2881cb0ef41Sopenharmony_ci 2891cb0ef41Sopenharmony_ci return {}; 2901cb0ef41Sopenharmony_ci } 2911cb0ef41Sopenharmony_ci 2921cb0ef41Sopenharmony_ci DCHECK(!result.is_null()); 2931cb0ef41Sopenharmony_ci DCHECK(result->is_turbofanned()); // TODO(v8:7700): Support Maglev. 2941cb0ef41Sopenharmony_ci DCHECK(CodeKindIsOptimizedJSFunction(result->kind())); 2951cb0ef41Sopenharmony_ci 2961cb0ef41Sopenharmony_ci DeoptimizationData data = 2971cb0ef41Sopenharmony_ci DeoptimizationData::cast(result->deoptimization_data()); 2981cb0ef41Sopenharmony_ci DCHECK_EQ(BytecodeOffset(data.OsrBytecodeOffset().value()), osr_offset); 2991cb0ef41Sopenharmony_ci DCHECK_GE(data.OsrPcOffset().value(), 0); 3001cb0ef41Sopenharmony_ci 3011cb0ef41Sopenharmony_ci if (FLAG_trace_osr) { 3021cb0ef41Sopenharmony_ci CodeTracer::Scope scope(isolate->GetCodeTracer()); 3031cb0ef41Sopenharmony_ci PrintF(scope.file(), 3041cb0ef41Sopenharmony_ci "[OSR - entry. function: %s, osr offset: %d, pc offset: %d]\n", 3051cb0ef41Sopenharmony_ci function->DebugNameCStr().get(), osr_offset.ToInt(), 3061cb0ef41Sopenharmony_ci data.OsrPcOffset().value()); 3071cb0ef41Sopenharmony_ci } 3081cb0ef41Sopenharmony_ci 3091cb0ef41Sopenharmony_ci if (function->feedback_vector().invocation_count() <= 1 && 3101cb0ef41Sopenharmony_ci !IsNone(function->tiering_state()) && 3111cb0ef41Sopenharmony_ci !IsInProgress(function->tiering_state())) { 3121cb0ef41Sopenharmony_ci // With lazy feedback allocation we may not have feedback for the 3131cb0ef41Sopenharmony_ci // initial part of the function that was executed before we allocated a 3141cb0ef41Sopenharmony_ci // feedback vector. Reset any tiering states for such functions. 3151cb0ef41Sopenharmony_ci // 3161cb0ef41Sopenharmony_ci // TODO(mythria): Instead of resetting the tiering state here we 3171cb0ef41Sopenharmony_ci // should only mark a function for optimization if it has sufficient 3181cb0ef41Sopenharmony_ci // feedback. We cannot do this currently since we OSR only after we mark 3191cb0ef41Sopenharmony_ci // a function for optimization. We should instead change it to be based 3201cb0ef41Sopenharmony_ci // based on number of ticks. 3211cb0ef41Sopenharmony_ci function->reset_tiering_state(); 3221cb0ef41Sopenharmony_ci } 3231cb0ef41Sopenharmony_ci 3241cb0ef41Sopenharmony_ci // TODO(mythria): Once we have OSR code cache we may not need to mark 3251cb0ef41Sopenharmony_ci // the function for non-concurrent compilation. We could arm the loops 3261cb0ef41Sopenharmony_ci // early so the second execution uses the already compiled OSR code and 3271cb0ef41Sopenharmony_ci // the optimization occurs concurrently off main thread. 3281cb0ef41Sopenharmony_ci if (!function->HasAvailableOptimizedCode() && 3291cb0ef41Sopenharmony_ci function->feedback_vector().invocation_count() > 1) { 3301cb0ef41Sopenharmony_ci // If we're not already optimized, set to optimize non-concurrently on the 3311cb0ef41Sopenharmony_ci // next call, otherwise we'd run unoptimized once more and potentially 3321cb0ef41Sopenharmony_ci // compile for OSR again. 3331cb0ef41Sopenharmony_ci if (FLAG_trace_osr) { 3341cb0ef41Sopenharmony_ci CodeTracer::Scope scope(isolate->GetCodeTracer()); 3351cb0ef41Sopenharmony_ci PrintF(scope.file(), 3361cb0ef41Sopenharmony_ci "[OSR - forcing synchronous optimization on next entry. function: " 3371cb0ef41Sopenharmony_ci "%s]\n", 3381cb0ef41Sopenharmony_ci function->DebugNameCStr().get()); 3391cb0ef41Sopenharmony_ci } 3401cb0ef41Sopenharmony_ci function->set_tiering_state(TieringState::kRequestTurbofan_Synchronous); 3411cb0ef41Sopenharmony_ci } 3421cb0ef41Sopenharmony_ci 3431cb0ef41Sopenharmony_ci return *result; 3441cb0ef41Sopenharmony_ci} 3451cb0ef41Sopenharmony_ci 3461cb0ef41Sopenharmony_cistatic Object CompileGlobalEval(Isolate* isolate, 3471cb0ef41Sopenharmony_ci Handle<i::Object> source_object, 3481cb0ef41Sopenharmony_ci Handle<SharedFunctionInfo> outer_info, 3491cb0ef41Sopenharmony_ci LanguageMode language_mode, 3501cb0ef41Sopenharmony_ci int eval_scope_position, int eval_position) { 3511cb0ef41Sopenharmony_ci Handle<Context> context(isolate->context(), isolate); 3521cb0ef41Sopenharmony_ci Handle<Context> native_context(context->native_context(), isolate); 3531cb0ef41Sopenharmony_ci 3541cb0ef41Sopenharmony_ci // Check if native context allows code generation from 3551cb0ef41Sopenharmony_ci // strings. Throw an exception if it doesn't. 3561cb0ef41Sopenharmony_ci MaybeHandle<String> source; 3571cb0ef41Sopenharmony_ci bool unknown_object; 3581cb0ef41Sopenharmony_ci std::tie(source, unknown_object) = Compiler::ValidateDynamicCompilationSource( 3591cb0ef41Sopenharmony_ci isolate, native_context, source_object); 3601cb0ef41Sopenharmony_ci // If the argument is an unhandled string time, bounce to GlobalEval. 3611cb0ef41Sopenharmony_ci if (unknown_object) { 3621cb0ef41Sopenharmony_ci return native_context->global_eval_fun(); 3631cb0ef41Sopenharmony_ci } 3641cb0ef41Sopenharmony_ci if (source.is_null()) { 3651cb0ef41Sopenharmony_ci Handle<Object> error_message = 3661cb0ef41Sopenharmony_ci native_context->ErrorMessageForCodeGenerationFromStrings(); 3671cb0ef41Sopenharmony_ci Handle<Object> error; 3681cb0ef41Sopenharmony_ci MaybeHandle<Object> maybe_error = isolate->factory()->NewEvalError( 3691cb0ef41Sopenharmony_ci MessageTemplate::kCodeGenFromStrings, error_message); 3701cb0ef41Sopenharmony_ci if (maybe_error.ToHandle(&error)) isolate->Throw(*error); 3711cb0ef41Sopenharmony_ci return ReadOnlyRoots(isolate).exception(); 3721cb0ef41Sopenharmony_ci } 3731cb0ef41Sopenharmony_ci 3741cb0ef41Sopenharmony_ci // Deal with a normal eval call with a string argument. Compile it 3751cb0ef41Sopenharmony_ci // and return the compiled function bound in the local context. 3761cb0ef41Sopenharmony_ci static const ParseRestriction restriction = NO_PARSE_RESTRICTION; 3771cb0ef41Sopenharmony_ci Handle<JSFunction> compiled; 3781cb0ef41Sopenharmony_ci ASSIGN_RETURN_ON_EXCEPTION_VALUE( 3791cb0ef41Sopenharmony_ci isolate, compiled, 3801cb0ef41Sopenharmony_ci Compiler::GetFunctionFromEval( 3811cb0ef41Sopenharmony_ci source.ToHandleChecked(), outer_info, context, language_mode, 3821cb0ef41Sopenharmony_ci restriction, kNoSourcePosition, eval_scope_position, eval_position), 3831cb0ef41Sopenharmony_ci ReadOnlyRoots(isolate).exception()); 3841cb0ef41Sopenharmony_ci return *compiled; 3851cb0ef41Sopenharmony_ci} 3861cb0ef41Sopenharmony_ci 3871cb0ef41Sopenharmony_ciRUNTIME_FUNCTION(Runtime_ResolvePossiblyDirectEval) { 3881cb0ef41Sopenharmony_ci HandleScope scope(isolate); 3891cb0ef41Sopenharmony_ci DCHECK_EQ(6, args.length()); 3901cb0ef41Sopenharmony_ci 3911cb0ef41Sopenharmony_ci Handle<Object> callee = args.at(0); 3921cb0ef41Sopenharmony_ci 3931cb0ef41Sopenharmony_ci // If "eval" didn't refer to the original GlobalEval, it's not a 3941cb0ef41Sopenharmony_ci // direct call to eval. 3951cb0ef41Sopenharmony_ci if (*callee != isolate->native_context()->global_eval_fun()) { 3961cb0ef41Sopenharmony_ci return *callee; 3971cb0ef41Sopenharmony_ci } 3981cb0ef41Sopenharmony_ci 3991cb0ef41Sopenharmony_ci DCHECK(is_valid_language_mode(args.smi_value_at(3))); 4001cb0ef41Sopenharmony_ci LanguageMode language_mode = static_cast<LanguageMode>(args.smi_value_at(3)); 4011cb0ef41Sopenharmony_ci Handle<SharedFunctionInfo> outer_info(args.at<JSFunction>(2)->shared(), 4021cb0ef41Sopenharmony_ci isolate); 4031cb0ef41Sopenharmony_ci return CompileGlobalEval(isolate, args.at<Object>(1), outer_info, 4041cb0ef41Sopenharmony_ci language_mode, args.smi_value_at(4), 4051cb0ef41Sopenharmony_ci args.smi_value_at(5)); 4061cb0ef41Sopenharmony_ci} 4071cb0ef41Sopenharmony_ci 4081cb0ef41Sopenharmony_ci} // namespace internal 4091cb0ef41Sopenharmony_ci} // namespace v8 410