• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Use of this source code is governed by a BSD-style license that can be
2 // Copyright 2021 the V8 project authors. All rights reserved.
3 // found in the LICENSE file.
4 
5 #ifndef V8_BASELINE_X64_BASELINE_COMPILER_X64_INL_H_
6 #define V8_BASELINE_X64_BASELINE_COMPILER_X64_INL_H_
7 
8 #include "src/base/macros.h"
9 #include "src/baseline/baseline-compiler.h"
10 #include "src/codegen/interface-descriptors.h"
11 
12 namespace v8 {
13 namespace internal {
14 namespace baseline {
15 
16 #define __ basm_.
17 
Prologue()18 void BaselineCompiler::Prologue() {
19   ASM_CODE_COMMENT(&masm_);
20   DCHECK_EQ(kJSFunctionRegister, kJavaScriptCallTargetRegister);
21   int max_frame_size =
22       bytecode_->frame_size() + max_call_args_ * kSystemPointerSize;
23   CallBuiltin<Builtin::kBaselineOutOfLinePrologue>(
24       kContextRegister, kJSFunctionRegister, kJavaScriptCallArgCountRegister,
25       max_frame_size, kJavaScriptCallNewTargetRegister, bytecode_);
26 
27   PrologueFillFrame();
28 }
29 
PrologueFillFrame()30 void BaselineCompiler::PrologueFillFrame() {
31   ASM_CODE_COMMENT(&masm_);
32   // Inlined register frame fill
33   interpreter::Register new_target_or_generator_register =
34       bytecode_->incoming_new_target_or_generator_register();
35   if (FLAG_debug_code) {
36     __ masm()->Cmp(kInterpreterAccumulatorRegister,
37                    handle(ReadOnlyRoots(local_isolate_).undefined_value(),
38                           local_isolate_));
39     __ masm()->Assert(equal, AbortReason::kUnexpectedValue);
40   }
41   int register_count = bytecode_->register_count();
42   // Magic value
43   const int kLoopUnrollSize = 8;
44   const int new_target_index = new_target_or_generator_register.index();
45   const bool has_new_target = new_target_index != kMaxInt;
46   if (has_new_target) {
47     DCHECK_LE(new_target_index, register_count);
48     for (int i = 0; i < new_target_index; i++) {
49       __ Push(kInterpreterAccumulatorRegister);
50     }
51     // Push new_target_or_generator.
52     __ Push(kJavaScriptCallNewTargetRegister);
53     register_count -= new_target_index + 1;
54   }
55   if (register_count < 2 * kLoopUnrollSize) {
56     // If the frame is small enough, just unroll the frame fill completely.
57     for (int i = 0; i < register_count; ++i) {
58       __ Push(kInterpreterAccumulatorRegister);
59     }
60   } else {
61     // Extract the first few registers to round to the unroll size.
62     int first_registers = register_count % kLoopUnrollSize;
63     for (int i = 0; i < first_registers; ++i) {
64       __ Push(kInterpreterAccumulatorRegister);
65     }
66     BaselineAssembler::ScratchRegisterScope scope(&basm_);
67     Register scratch = scope.AcquireScratch();
68     __ Move(scratch, register_count / kLoopUnrollSize);
69     // We enter the loop unconditionally, so make sure we need to loop at least
70     // once.
71     DCHECK_GT(register_count / kLoopUnrollSize, 0);
72     Label loop;
73     __ Bind(&loop);
74     for (int i = 0; i < kLoopUnrollSize; ++i) {
75       __ Push(kInterpreterAccumulatorRegister);
76     }
77     __ masm()->decl(scratch);
78     __ masm()->j(greater, &loop);
79   }
80 }
81 
VerifyFrameSize()82 void BaselineCompiler::VerifyFrameSize() {
83   ASM_CODE_COMMENT(&masm_);
84   __ Move(kScratchRegister, rsp);
85   __ masm()->addq(kScratchRegister,
86                   Immediate(InterpreterFrameConstants::kFixedFrameSizeFromFp +
87                             bytecode_->frame_size()));
88   __ masm()->cmpq(kScratchRegister, rbp);
89   __ masm()->Assert(equal, AbortReason::kUnexpectedStackPointer);
90 }
91 
92 #undef __
93 
94 }  // namespace baseline
95 }  // namespace internal
96 }  // namespace v8
97 
98 #endif  // V8_BASELINE_X64_BASELINE_COMPILER_X64_INL_H_
99