5 #ifndef V8_CODE_STUBS_H_ 6 #define V8_CODE_STUBS_H_ 8 #include "src/frames.h" 9 #include "src/interface-descriptors.h" 10 #include "src/type-hints.h" 16 class CodeStubDescriptor;
21 class CodeAssemblerState;
25 #define CODE_STUB_LIST_ALL_PLATFORMS(V) \ 32 #if V8_TARGET_ARCH_ARM 33 #define CODE_STUB_LIST_ARM(V) V(DirectCEntry) 36 #define CODE_STUB_LIST_ARM(V) 40 #if V8_TARGET_ARCH_ARM64 41 #define CODE_STUB_LIST_ARM64(V) V(DirectCEntry) 44 #define CODE_STUB_LIST_ARM64(V) 48 #ifdef V8_TARGET_ARCH_PPC 49 #define CODE_STUB_LIST_PPC(V) V(DirectCEntry) 51 #define CODE_STUB_LIST_PPC(V) 55 #if V8_TARGET_ARCH_MIPS 56 #define CODE_STUB_LIST_MIPS(V) V(DirectCEntry) 57 #elif V8_TARGET_ARCH_MIPS64 58 #define CODE_STUB_LIST_MIPS(V) V(DirectCEntry) 60 #define CODE_STUB_LIST_MIPS(V) 64 #ifdef V8_TARGET_ARCH_S390 65 #define CODE_STUB_LIST_S390(V) V(DirectCEntry) 67 #define CODE_STUB_LIST_S390(V) 71 #define CODE_STUB_LIST(V) \ 72 CODE_STUB_LIST_ALL_PLATFORMS(V) \ 73 CODE_STUB_LIST_ARM(V) \ 74 CODE_STUB_LIST_ARM64(V) \ 75 CODE_STUB_LIST_PPC(V) \ 76 CODE_STUB_LIST_MIPS(V) \ 77 CODE_STUB_LIST_S390(V) 79 static const int kHasReturnedMinusZeroSentinel = 1;
87 #define DEF_ENUM(name) name, 88 CODE_STUB_LIST(DEF_ENUM)
96 static Major MajorKeyFromKey(
uint32_t key) {
97 return static_cast<Major
>(MajorKeyBits::decode(key));
100 return MinorKeyBits::decode(key);
104 static Major GetMajorKey(
const Code code_stub);
106 static uint32_t NoCacheKey() {
return MajorKeyBits::encode(NoCache); }
108 static const char* MajorName(Major major_key);
110 explicit CodeStub(
Isolate* isolate) : minor_key_(0), isolate_(isolate) {}
119 virtual bool SometimesSetsUpAFrame() {
return true; }
122 bool FindCodeInCache(
Code* code_out);
126 virtual int GetStackParameterCount()
const {
127 return GetCallInterfaceDescriptor().GetStackParameterCount();
136 virtual Major MajorKey()
const = 0;
137 uint32_t MinorKey()
const {
return minor_key_; }
139 friend std::ostream& operator<<(std::ostream& os,
const CodeStub& s) {
144 Isolate* isolate()
const {
return isolate_; }
145 void set_isolate(
Isolate* isolate) {
146 DCHECK_NOT_NULL(isolate);
147 DCHECK(isolate_ ==
nullptr || isolate_ == isolate);
151 void DeleteStubFromCacheForTesting();
155 : minor_key_(MinorKeyFromKey(key)), isolate_(isolate) {}
164 virtual Movability NeedsImmovableCode() {
return kMovable; }
166 virtual void PrintName(std::ostream& os)
const;
167 virtual void PrintBaseName(std::ostream& os)
const;
168 virtual void PrintState(std::ostream& os)
const { ; }
172 DCHECK(static_cast<int>(MajorKey()) < NUMBER_OF_IDS);
173 return MinorKeyBits::encode(MinorKey()) | MajorKeyBits::encode(MajorKey());
185 typedef void (*DispatchedCall)(
CodeStub* stub,
void** value_out);
187 DispatchedCall call);
189 static void GetCodeDispatchCall(
CodeStub* stub,
void** value_out);
191 STATIC_ASSERT(NUMBER_OF_IDS < (1 << kStubMajorKeyBits));
192 class MajorKeyBits:
public BitField<uint32_t, 0, kStubMajorKeyBits> {};
193 class MinorKeyBits:
public BitField<uint32_t,
194 kStubMajorKeyBits, kStubMinorKeyBits> {};
196 friend class BreakPointIterator;
202 #define DEFINE_CODE_STUB_BASE(NAME, SUPER) \ 204 NAME(uint32_t key, Isolate* isolate) : SUPER(key, isolate) {} \ 207 DISALLOW_COPY_AND_ASSIGN(NAME) 210 #define DEFINE_CODE_STUB(NAME, SUPER) \ 212 inline Major MajorKey() const override { return NAME; }; \ 214 DEFINE_CODE_STUB_BASE(NAME##Stub, SUPER) 217 #define DEFINE_PLATFORM_CODE_STUB(NAME, SUPER) \ 219 void Generate(MacroAssembler* masm) override; \ 220 DEFINE_CODE_STUB(NAME, SUPER) 223 #define DEFINE_TURBOFAN_CODE_STUB(NAME, SUPER) \ 225 void GenerateAssembly(compiler::CodeAssemblerState* state) const override; \ 226 DEFINE_CODE_STUB(NAME, SUPER) 228 #define DEFINE_CALL_INTERFACE_DESCRIPTOR(NAME) \ 230 typedef NAME##Descriptor Descriptor; \ 231 CallInterfaceDescriptor GetCallInterfaceDescriptor() const override { \ 232 return Descriptor(); \ 238 #define DEFINE_NULL_CALL_INTERFACE_DESCRIPTOR() \ 240 CallInterfaceDescriptor GetCallInterfaceDescriptor() const override { \ 242 return CallInterfaceDescriptor(); \ 264 enum StubFunctionMode { NOT_JS_FUNCTION_STUB_MODE, JS_FUNCTION_STUB_MODE };
273 void Initialize(
Address deoptimization_handler = kNullAddress,
274 int hint_stack_parameter_count = -1,
275 StubFunctionMode function_mode = NOT_JS_FUNCTION_STUB_MODE);
276 void Initialize(
Register stack_parameter_count,
277 Address deoptimization_handler = kNullAddress,
278 int hint_stack_parameter_count = -1,
279 StubFunctionMode function_mode = NOT_JS_FUNCTION_STUB_MODE);
281 void SetMissHandler(Runtime::FunctionId
id) {
282 miss_handler_id_ = id;
283 miss_handler_ = ExternalReference::Create(Runtime::FunctionForId(
id));
284 has_miss_handler_ =
true;
287 DCHECK(!stack_parameter_count_.is_valid());
291 call_descriptor_ = std::move(d);
295 int GetRegisterParameterCount()
const {
296 return call_descriptor().GetRegisterParameterCount();
299 int GetStackParameterCount()
const {
300 return call_descriptor().GetStackParameterCount();
303 int GetParameterCount()
const {
304 return call_descriptor().GetParameterCount();
307 Register GetRegisterParameter(
int index)
const {
308 return call_descriptor().GetRegisterParameter(index);
312 return call_descriptor().GetParameterType(index);
316 DCHECK(has_miss_handler_);
317 return miss_handler_;
320 Runtime::FunctionId miss_handler_id()
const {
321 DCHECK(has_miss_handler_);
322 return miss_handler_id_;
325 bool has_miss_handler()
const {
326 return has_miss_handler_;
329 int GetHandlerParameterCount()
const {
330 int params = GetParameterCount();
331 if (PassesArgumentsToDeoptimizationHandler()) {
337 int hint_stack_parameter_count()
const {
return hint_stack_parameter_count_; }
338 Register stack_parameter_count()
const {
return stack_parameter_count_; }
339 StubFunctionMode function_mode()
const {
return function_mode_; }
340 Address deoptimization_handler()
const {
return deoptimization_handler_; }
343 bool PassesArgumentsToDeoptimizationHandler()
const {
344 return stack_parameter_count_.is_valid();
352 int hint_stack_parameter_count_;
353 StubFunctionMode function_mode_;
355 Address deoptimization_handler_;
358 Runtime::FunctionId miss_handler_id_;
359 bool has_miss_handler_;
365 #if V8_TARGET_ARCH_IA32 366 #elif V8_TARGET_ARCH_X64 367 #elif V8_TARGET_ARCH_ARM64 368 #include "src/arm64/code-stubs-arm64.h" 369 #elif V8_TARGET_ARCH_ARM 370 #include "src/arm/code-stubs-arm.h" 371 #elif V8_TARGET_ARCH_PPC 372 #include "src/ppc/code-stubs-ppc.h" 373 #elif V8_TARGET_ARCH_MIPS 374 #include "src/mips/code-stubs-mips.h" 375 #elif V8_TARGET_ARCH_MIPS64 376 #include "src/mips64/code-stubs-mips64.h" 377 #elif V8_TARGET_ARCH_S390 378 #include "src/s390/code-stubs-s390.h" 380 #error Unsupported target architecture. 390 static const int kArgBits = 7;
391 static const int kArgMax = (1 << kArgBits) - 1;
396 CHECK_LE(argc, kArgMax);
397 minor_key_ = ArgumentBits::encode(argc);
401 int argc()
const {
return ArgumentBits::decode(minor_key_); }
403 class ArgumentBits :
public BitField<int, 0, kArgBits> {};
407 DEFINE_CALL_INTERFACE_DESCRIPTOR(ApiCallback);
420 DEFINE_CALL_INTERFACE_DESCRIPTOR(ApiGetter);
426 enum class SpecialTarget {
kNone, kRunMicrotasks };
429 DCHECK(
type == StackFrame::ENTRY ||
type == StackFrame::CONSTRUCT_ENTRY);
430 minor_key_ = StackFrameTypeBits::encode(
type) |
431 SpecialTargetBits::encode(SpecialTarget::kNone);
436 minor_key_ = StackFrameTypeBits::encode(StackFrame::ENTRY) |
437 SpecialTargetBits::encode(target);
443 void PrintName(std::ostream& os)
const override {
444 os << (
type() == StackFrame::ENTRY ?
"JSEntryStub" 445 :
"JSConstructEntryStub");
448 StackFrame::Type
type()
const {
449 return StackFrameTypeBits::decode(minor_key_);
452 SpecialTarget special_target()
const {
453 return SpecialTargetBits::decode(minor_key_);
457 switch (special_target()) {
458 case SpecialTarget::kNone:
459 return (
type() == StackFrame::CONSTRUCT_ENTRY)
460 ? BUILTIN_CODE(isolate(), JSConstructEntryTrampoline)
461 : BUILTIN_CODE(isolate(), JSEntryTrampoline);
462 case SpecialTarget::kRunMicrotasks:
463 return BUILTIN_CODE(isolate(), RunMicrotasks);
469 class StackFrameTypeBits :
public BitField<StackFrame::Type, 0, 5> {};
470 class SpecialTargetBits
471 :
public BitField<SpecialTarget, StackFrameTypeBits::kNext, 1> {};
475 DEFINE_NULL_CALL_INTERFACE_DESCRIPTOR();
479 #undef DEFINE_CALL_INTERFACE_DESCRIPTOR 480 #undef DEFINE_PLATFORM_CODE_STUB 481 #undef DEFINE_CODE_STUB 482 #undef DEFINE_CODE_STUB_BASE 487 #endif // V8_CODE_STUBS_H_