summaryrefslogtreecommitdiffstats
path: root/js/src/jit/BaselineCacheIRCompiler.h
blob: 91d1aa55f0adea0bb3d8c575c4aa3e3659936202 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
 * vim: set ts=8 sts=2 et sw=2 tw=80:
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

#ifndef jit_BaselineCacheIRCompiler_h
#define jit_BaselineCacheIRCompiler_h

#include "mozilla/Attributes.h"
#include "mozilla/Maybe.h"

#include <stddef.h>
#include <stdint.h>

#include "jstypes.h"

#include "jit/CacheIR.h"
#include "jit/CacheIRCompiler.h"
#include "jit/CacheIROpsGenerated.h"
#include "jit/CacheIRReader.h"

struct JS_PUBLIC_API JSContext;

class JSScript;

namespace js {
namespace jit {

class CacheIRWriter;
class ICFallbackStub;
class ICScript;
class JitCode;
class Label;
class MacroAssembler;

struct Address;
struct Register;

enum class ICAttachResult { Attached, DuplicateStub, TooLarge, OOM };

bool TryFoldingStubs(JSContext* cx, ICFallbackStub* fallback, JSScript* script,
                     ICScript* icScript);

ICAttachResult AttachBaselineCacheIRStub(JSContext* cx,
                                         const CacheIRWriter& writer,
                                         CacheKind kind, JSScript* outerScript,
                                         ICScript* icScript,
                                         ICFallbackStub* stub,
                                         const char* name);

// BaselineCacheIRCompiler compiles CacheIR to BaselineIC native code.
class MOZ_RAII BaselineCacheIRCompiler : public CacheIRCompiler {
  bool makesGCCalls_;
  Register baselineFrameReg_ = FramePointer;

  // This register points to the baseline frame of the caller. It should only
  // be used before we enter a stub frame. This is normally the frame pointer
  // register, but with --enable-ic-frame-pointers we have to allocate a
  // separate register.
  inline Register baselineFrameReg() {
    MOZ_ASSERT(!enteredStubFrame_);
    return baselineFrameReg_;
  }

  [[nodiscard]] bool emitStoreSlotShared(bool isFixed, ObjOperandId objId,
                                         uint32_t offsetOffset,
                                         ValOperandId rhsId);
  [[nodiscard]] bool emitAddAndStoreSlotShared(
      CacheOp op, ObjOperandId objId, uint32_t offsetOffset, ValOperandId rhsId,
      uint32_t newShapeOffset, mozilla::Maybe<uint32_t> numNewSlotsOffset);

  bool updateArgc(CallFlags flags, Register argcReg, Register scratch);
  void loadStackObject(ArgumentKind kind, CallFlags flags, Register argcReg,
                       Register dest);
  void pushArguments(Register argcReg, Register calleeReg, Register scratch,
                     Register scratch2, CallFlags flags, uint32_t argcFixed,
                     bool isJitCall);
  void pushStandardArguments(Register argcReg, Register scratch,
                             Register scratch2, uint32_t argcFixed,
                             bool isJitCall, bool isConstructing);
  void pushArrayArguments(Register argcReg, Register scratch, Register scratch2,
                          bool isJitCall, bool isConstructing);
  void pushFunCallArguments(Register argcReg, Register calleeReg,
                            Register scratch, Register scratch2,
                            uint32_t argcFixed, bool isJitCall);
  void pushFunApplyArgsObj(Register argcReg, Register calleeReg,
                           Register scratch, Register scratch2, bool isJitCall);
  void pushFunApplyNullUndefinedArguments(Register calleeReg, bool isJitCall);
  void pushBoundFunctionArguments(Register argcReg, Register calleeReg,
                                  Register scratch, Register scratch2,
                                  CallFlags flags, uint32_t numBoundArgs,
                                  bool isJitCall);
  void createThis(Register argcReg, Register calleeReg, Register scratch,
                  CallFlags flags, bool isBoundFunction);
  template <typename T>
  void storeThis(const T& newThis, Register argcReg, CallFlags flags);
  void updateReturnValue();

  enum class NativeCallType { Native, ClassHook };
  bool emitCallNativeShared(NativeCallType callType, ObjOperandId calleeId,
                            Int32OperandId argcId, CallFlags flags,
                            uint32_t argcFixed,
                            mozilla::Maybe<bool> ignoresReturnValue,
                            mozilla::Maybe<uint32_t> targetOffset);

  enum class StringCode { CodeUnit, CodePoint };
  bool emitStringFromCodeResult(Int32OperandId codeId, StringCode stringCode);

  void emitAtomizeString(Register str, Register temp, Label* failure);

  bool emitCallScriptedGetterShared(ValOperandId receiverId,
                                    uint32_t getterOffset, bool sameRealm,
                                    uint32_t nargsAndFlagsOffset,
                                    mozilla::Maybe<uint32_t> icScriptOffset);
  bool emitCallScriptedSetterShared(ObjOperandId receiverId,
                                    uint32_t setterOffset, ValOperandId rhsId,
                                    bool sameRealm,
                                    uint32_t nargsAndFlagsOffset,
                                    mozilla::Maybe<uint32_t> icScriptOffset);

  BaselineICPerfSpewer perfSpewer_;

 public:
  BaselineICPerfSpewer& perfSpewer() { return perfSpewer_; }

  friend class AutoStubFrame;

  BaselineCacheIRCompiler(JSContext* cx, TempAllocator& alloc,
                          const CacheIRWriter& writer, uint32_t stubDataOffset);

  [[nodiscard]] bool init(CacheKind kind);

  template <typename Fn, Fn fn>
  void callVM(MacroAssembler& masm);

  JitCode* compile();

  bool makesGCCalls() const;

  Address stubAddress(uint32_t offset) const;

 private:
  CACHE_IR_COMPILER_UNSHARED_GENERATED
};

}  // namespace jit
}  // namespace js

#endif /* jit_BaselineCacheIRCompiler_h */