1// Copyright 2020 the V8 project authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "src/baseline/baseline.h"
6
7#include "src/handles/maybe-handles.h"
8#include "src/objects/shared-function-info-inl.h"
9
10// TODO(v8:11421): Remove #if once baseline compiler is ported to other
11// architectures.
12#include "src/flags/flags.h"
13#if ENABLE_SPARKPLUG
14
15#include "src/baseline/baseline-assembler-inl.h"
16#include "src/baseline/baseline-compiler.h"
17#include "src/debug/debug.h"
18#include "src/heap/factory-inl.h"
19#include "src/logging/runtime-call-stats-scope.h"
20#include "src/objects/script-inl.h"
21
22namespace v8 {
23namespace internal {
24
25bool CanCompileWithBaseline(Isolate* isolate, SharedFunctionInfo shared) {
26  DisallowGarbageCollection no_gc;
27
28  // Check that baseline compiler is enabled.
29  if (!FLAG_sparkplug) return false;
30
31  // Check that short builtin calls are enabled if needed.
32  if (FLAG_sparkplug_needs_short_builtins &&
33      !isolate->is_short_builtin_calls_enabled()) {
34    return false;
35  }
36
37  // Check if we actually have bytecode.
38  if (!shared.HasBytecodeArray()) return false;
39
40  // Do not optimize when debugger needs to hook into every call.
41  if (isolate->debug()->needs_check_on_function_call()) return false;
42
43  // Functions with breakpoints have to stay interpreted.
44  if (shared.HasBreakInfo()) return false;
45
46  // Functions with instrumented bytecode can't be baseline compiled since the
47  // baseline code's bytecode array pointer is immutable.
48  if (shared.HasDebugInfo() &&
49      shared.GetDebugInfo().HasInstrumentedBytecodeArray()) {
50    return false;
51  }
52
53  // Do not baseline compile if function doesn't pass sparkplug_filter.
54  if (!shared.PassesFilter(FLAG_sparkplug_filter)) return false;
55
56  return true;
57}
58
59MaybeHandle<Code> GenerateBaselineCode(Isolate* isolate,
60                                       Handle<SharedFunctionInfo> shared) {
61  RCS_SCOPE(isolate, RuntimeCallCounterId::kCompileBaseline);
62  Handle<BytecodeArray> bytecode(shared->GetBytecodeArray(isolate), isolate);
63  LocalIsolate* local_isolate = isolate->main_thread_local_isolate();
64  baseline::BaselineCompiler compiler(local_isolate, shared, bytecode);
65  compiler.GenerateCode();
66  MaybeHandle<Code> code = compiler.Build(local_isolate);
67  if (FLAG_print_code && !code.is_null()) {
68    code.ToHandleChecked()->Print();
69  }
70  return code;
71}
72
73void EmitReturnBaseline(MacroAssembler* masm) {
74  baseline::BaselineAssembler::EmitReturn(masm);
75}
76
77}  // namespace internal
78}  // namespace v8
79
80#else
81
82namespace v8 {
83namespace internal {
84
85bool CanCompileWithBaseline(Isolate* isolate, SharedFunctionInfo shared) {
86  return false;
87}
88
89MaybeHandle<Code> GenerateBaselineCode(Isolate* isolate,
90                                       Handle<SharedFunctionInfo> shared) {
91  UNREACHABLE();
92}
93
94void EmitReturnBaseline(MacroAssembler* masm) { UNREACHABLE(); }
95
96}  // namespace internal
97}  // namespace v8
98
99#endif
100