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