Line data Source code
1 : // Copyright 2012 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 : #ifndef V8_CODE_STUBS_H_
6 : #define V8_CODE_STUBS_H_
7 :
8 : #include "src/allocation.h"
9 : #include "src/assembler.h"
10 : #include "src/codegen.h"
11 : #include "src/factory.h"
12 : #include "src/find-and-replace-pattern.h"
13 : #include "src/globals.h"
14 : #include "src/ic/ic-state.h"
15 : #include "src/interface-descriptors.h"
16 : #include "src/macro-assembler.h"
17 : #include "src/ostreams.h"
18 : #include "src/type-hints.h"
19 :
20 : namespace v8 {
21 : namespace internal {
22 :
23 : // Forward declarations.
24 : class CodeStubAssembler;
25 : namespace compiler {
26 : class CodeAssemblerLabel;
27 : class CodeAssemblerState;
28 : class Node;
29 : }
30 :
31 : // List of code stubs used on all platforms.
32 : #define CODE_STUB_LIST_ALL_PLATFORMS(V) \
33 : /* --- PlatformCodeStubs --- */ \
34 : V(ArrayConstructor) \
35 : V(BinaryOpICWithAllocationSite) \
36 : V(CallApiCallback) \
37 : V(CallApiGetter) \
38 : V(CallConstruct) \
39 : V(CallIC) \
40 : V(CEntry) \
41 : V(CompareIC) \
42 : V(DoubleToI) \
43 : V(InternalArrayConstructor) \
44 : V(JSEntry) \
45 : V(MathPow) \
46 : V(ProfileEntryHook) \
47 : V(RecordWrite) \
48 : V(StoreBufferOverflow) \
49 : V(StoreSlowElement) \
50 : V(SubString) \
51 : V(NameDictionaryLookup) \
52 : /* This can be removed once there are no */ \
53 : /* more deopting Hydrogen stubs. */ \
54 : V(StubFailureTrampoline) \
55 : /* These are only called from FCG */ \
56 : /* They can be removed when only the TF */ \
57 : /* version of the corresponding stub is */ \
58 : /* used universally */ \
59 : V(CallICTrampoline) \
60 : /* --- HydrogenCodeStubs --- */ \
61 : /* These should never be ported to TF */ \
62 : /* because they are either used only by */ \
63 : /* FCG/Crankshaft or are deprecated */ \
64 : V(BinaryOpIC) \
65 : V(BinaryOpWithAllocationSite) \
66 : V(ToBooleanIC) \
67 : V(TransitionElementsKind) \
68 : /* --- TurboFanCodeStubs --- */ \
69 : V(AllocateHeapNumber) \
70 : V(ArrayNoArgumentConstructor) \
71 : V(ArraySingleArgumentConstructor) \
72 : V(ArrayNArgumentsConstructor) \
73 : V(CreateAllocationSite) \
74 : V(CreateWeakCell) \
75 : V(StringLength) \
76 : V(InternalArrayNoArgumentConstructor) \
77 : V(InternalArraySingleArgumentConstructor) \
78 : V(ElementsTransitionAndStore) \
79 : V(KeyedLoadSloppyArguments) \
80 : V(KeyedStoreSloppyArguments) \
81 : V(LoadScriptContextField) \
82 : V(StoreScriptContextField) \
83 : V(NumberToString) \
84 : V(StringAdd) \
85 : V(GetProperty) \
86 : V(StoreFastElement) \
87 : V(StoreInterceptor) \
88 : V(LoadIndexedInterceptor) \
89 : V(GrowArrayElements)
90 :
91 : // List of code stubs only used on ARM 32 bits platforms.
92 : #if V8_TARGET_ARCH_ARM
93 : #define CODE_STUB_LIST_ARM(V) V(DirectCEntry)
94 :
95 : #else
96 : #define CODE_STUB_LIST_ARM(V)
97 : #endif
98 :
99 : // List of code stubs only used on ARM 64 bits platforms.
100 : #if V8_TARGET_ARCH_ARM64
101 : #define CODE_STUB_LIST_ARM64(V) \
102 : V(DirectCEntry) \
103 : V(RestoreRegistersState) \
104 : V(StoreRegistersState)
105 :
106 : #else
107 : #define CODE_STUB_LIST_ARM64(V)
108 : #endif
109 :
110 : // List of code stubs only used on PPC platforms.
111 : #ifdef V8_TARGET_ARCH_PPC
112 : #define CODE_STUB_LIST_PPC(V) \
113 : V(DirectCEntry) \
114 : V(StoreRegistersState) \
115 : V(RestoreRegistersState)
116 : #else
117 : #define CODE_STUB_LIST_PPC(V)
118 : #endif
119 :
120 : // List of code stubs only used on MIPS platforms.
121 : #if V8_TARGET_ARCH_MIPS
122 : #define CODE_STUB_LIST_MIPS(V) \
123 : V(DirectCEntry) \
124 : V(RestoreRegistersState) \
125 : V(StoreRegistersState)
126 : #elif V8_TARGET_ARCH_MIPS64
127 : #define CODE_STUB_LIST_MIPS(V) \
128 : V(DirectCEntry) \
129 : V(RestoreRegistersState) \
130 : V(StoreRegistersState)
131 : #else
132 : #define CODE_STUB_LIST_MIPS(V)
133 : #endif
134 :
135 : // List of code stubs only used on S390 platforms.
136 : #ifdef V8_TARGET_ARCH_S390
137 : #define CODE_STUB_LIST_S390(V) \
138 : V(DirectCEntry) \
139 : V(StoreRegistersState) \
140 : V(RestoreRegistersState)
141 : #else
142 : #define CODE_STUB_LIST_S390(V)
143 : #endif
144 :
145 : // Combined list of code stubs.
146 : #define CODE_STUB_LIST(V) \
147 : CODE_STUB_LIST_ALL_PLATFORMS(V) \
148 : CODE_STUB_LIST_ARM(V) \
149 : CODE_STUB_LIST_ARM64(V) \
150 : CODE_STUB_LIST_PPC(V) \
151 : CODE_STUB_LIST_MIPS(V) \
152 : CODE_STUB_LIST_S390(V)
153 :
154 : static const int kHasReturnedMinusZeroSentinel = 1;
155 :
156 : // Stub is base classes of all stubs.
157 : class CodeStub BASE_EMBEDDED {
158 : public:
159 : enum Major {
160 : // TODO(mvstanton): eliminate the NoCache key by getting rid
161 : // of the non-monomorphic-cache.
162 : NoCache = 0, // marker for stubs that do custom caching]
163 : #define DEF_ENUM(name) name,
164 : CODE_STUB_LIST(DEF_ENUM)
165 : #undef DEF_ENUM
166 : NUMBER_OF_IDS
167 : };
168 :
169 : // Retrieve the code for the stub. Generate the code if needed.
170 : Handle<Code> GetCode();
171 :
172 : // Retrieve the code for the stub, make and return a copy of the code.
173 : Handle<Code> GetCodeCopy(const FindAndReplacePattern& pattern);
174 :
175 : static Major MajorKeyFromKey(uint32_t key) {
176 : return static_cast<Major>(MajorKeyBits::decode(key));
177 : }
178 : static uint32_t MinorKeyFromKey(uint32_t key) {
179 : return MinorKeyBits::decode(key);
180 : }
181 :
182 : // Gets the major key from a code object that is a code stub or binary op IC.
183 : static Major GetMajorKey(Code* code_stub) {
184 : return MajorKeyFromKey(code_stub->stub_key());
185 : }
186 :
187 : static uint32_t NoCacheKey() { return MajorKeyBits::encode(NoCache); }
188 :
189 : static const char* MajorName(Major major_key);
190 :
191 10839428 : explicit CodeStub(Isolate* isolate) : minor_key_(0), isolate_(isolate) {}
192 1014662 : virtual ~CodeStub() {}
193 :
194 : static void GenerateStubsAheadOfTime(Isolate* isolate);
195 : static void GenerateFPStubs(Isolate* isolate);
196 :
197 : // Some stubs put untagged junk on the stack that cannot be scanned by the
198 : // GC. This means that we must be statically sure that no GC can occur while
199 : // they are running. If that is the case they should override this to return
200 : // true, which will cause an assertion if we try to call something that can
201 : // GC or if we try to put a stack frame on top of the junk, which would not
202 : // result in a traversable stack.
203 0 : virtual bool SometimesSetsUpAFrame() { return true; }
204 :
205 : // Lookup the code in the (possibly custom) cache.
206 : bool FindCodeInCache(Code** code_out);
207 :
208 : virtual CallInterfaceDescriptor GetCallInterfaceDescriptor() const = 0;
209 :
210 0 : virtual int GetStackParameterCount() const {
211 0 : return GetCallInterfaceDescriptor().GetStackParameterCount();
212 : }
213 :
214 0 : virtual void InitializeDescriptor(CodeStubDescriptor* descriptor) {}
215 :
216 : static void InitializeDescriptor(Isolate* isolate, uint32_t key,
217 : CodeStubDescriptor* desc);
218 :
219 : static MaybeHandle<Code> GetCode(Isolate* isolate, uint32_t key);
220 :
221 : // Returns information for computing the number key.
222 : virtual Major MajorKey() const = 0;
223 : uint32_t MinorKey() const { return minor_key_; }
224 :
225 : // BinaryOpStub needs to override this.
226 : virtual Code::Kind GetCodeKind() const;
227 :
228 95221 : virtual ExtraICState GetExtraICState() const { return kNoExtraICState; }
229 :
230 : Code::Flags GetCodeFlags() const;
231 :
232 : friend std::ostream& operator<<(std::ostream& os, const CodeStub& s) {
233 286632 : s.PrintName(os);
234 : return os;
235 : }
236 :
237 : Isolate* isolate() const { return isolate_; }
238 :
239 : void DeleteStubFromCacheForTesting();
240 :
241 : protected:
242 : CodeStub(uint32_t key, Isolate* isolate)
243 53856 : : minor_key_(MinorKeyFromKey(key)), isolate_(isolate) {}
244 :
245 : // Generates the assembler code for the stub.
246 : virtual Handle<Code> GenerateCode() = 0;
247 :
248 : // Returns whether the code generated for this stub needs to be allocated as
249 : // a fixed (non-moveable) code object.
250 108142 : virtual bool NeedsImmovableCode() { return false; }
251 :
252 : virtual void PrintName(std::ostream& os) const; // NOLINT
253 : virtual void PrintBaseName(std::ostream& os) const; // NOLINT
254 129074 : virtual void PrintState(std::ostream& os) const { ; } // NOLINT
255 :
256 : // Computes the key based on major and minor.
257 10496773 : uint32_t GetKey() {
258 : DCHECK(static_cast<int>(MajorKey()) < NUMBER_OF_IDS);
259 10496773 : return MinorKeyBits::encode(MinorKey()) | MajorKeyBits::encode(MajorKey());
260 : }
261 :
262 : uint32_t minor_key_;
263 :
264 : private:
265 : // Perform bookkeeping required after code generation when stub code is
266 : // initially generated.
267 : void RecordCodeGeneration(Handle<Code> code);
268 :
269 : // Finish the code object after it has been generated.
270 208611 : virtual void FinishCode(Handle<Code> code) { }
271 :
272 : // Activate newly generated stub. Is called after
273 : // registering stub in the stub cache.
274 191489 : virtual void Activate(Code* code) { }
275 :
276 : // Add the code to a specialized cache, specific to an individual
277 : // stub type. Please note, this method must add the code object to a
278 : // roots object, otherwise we will remove the code during GC.
279 2072 : virtual void AddToSpecialCache(Handle<Code> new_object) { }
280 :
281 : // Find code in a specialized cache, work is delegated to the specific stub.
282 2072 : virtual bool FindCodeInSpecialCache(Code** code_out) {
283 2072 : return false;
284 : }
285 :
286 : // If a stub uses a special cache override this.
287 8409786 : virtual bool UseSpecialCache() { return false; }
288 :
289 : // We use this dispatch to statically instantiate the correct code stub for
290 : // the given stub key and call the passed function with that code stub.
291 : typedef void (*DispatchedCall)(CodeStub* stub, void** value_out);
292 : static void Dispatch(Isolate* isolate, uint32_t key, void** value_out,
293 : DispatchedCall call);
294 :
295 : static void GetCodeDispatchCall(CodeStub* stub, void** value_out);
296 :
297 : STATIC_ASSERT(NUMBER_OF_IDS < (1 << kStubMajorKeyBits));
298 : class MajorKeyBits: public BitField<uint32_t, 0, kStubMajorKeyBits> {};
299 : class MinorKeyBits: public BitField<uint32_t,
300 : kStubMajorKeyBits, kStubMinorKeyBits> {}; // NOLINT
301 :
302 : friend class BreakPointIterator;
303 :
304 : Isolate* isolate_;
305 : };
306 :
307 :
308 : #define DEFINE_CODE_STUB_BASE(NAME, SUPER) \
309 : public: \
310 : NAME(uint32_t key, Isolate* isolate) : SUPER(key, isolate) {} \
311 : \
312 : private: \
313 : DISALLOW_COPY_AND_ASSIGN(NAME)
314 :
315 :
316 : #define DEFINE_CODE_STUB(NAME, SUPER) \
317 : public: \
318 : inline Major MajorKey() const override { return NAME; }; \
319 : \
320 : DEFINE_CODE_STUB_BASE(NAME##Stub, SUPER)
321 :
322 :
323 : #define DEFINE_PLATFORM_CODE_STUB(NAME, SUPER) \
324 : private: \
325 : void Generate(MacroAssembler* masm) override; \
326 : DEFINE_CODE_STUB(NAME, SUPER)
327 :
328 :
329 : #define DEFINE_HYDROGEN_CODE_STUB(NAME, SUPER) \
330 : public: \
331 : void InitializeDescriptor(CodeStubDescriptor* descriptor) override; \
332 : Handle<Code> GenerateCode() override; \
333 : DEFINE_CODE_STUB(NAME, SUPER)
334 :
335 : #define DEFINE_TURBOFAN_CODE_STUB(NAME, SUPER) \
336 : public: \
337 : void GenerateAssembly(compiler::CodeAssemblerState* state) const override; \
338 : DEFINE_CODE_STUB(NAME, SUPER)
339 :
340 : #define DEFINE_HANDLER_CODE_STUB(NAME, SUPER) \
341 : public: \
342 : Handle<Code> GenerateCode() override; \
343 : DEFINE_CODE_STUB(NAME, SUPER)
344 :
345 : #define DEFINE_CALL_INTERFACE_DESCRIPTOR(NAME) \
346 : public: \
347 : typedef NAME##Descriptor Descriptor; \
348 : CallInterfaceDescriptor GetCallInterfaceDescriptor() const override { \
349 : return Descriptor(isolate()); \
350 : }
351 :
352 : // There are some code stubs we just can't describe right now with a
353 : // CallInterfaceDescriptor. Isolate behavior for those cases with this macro.
354 : // An attempt to retrieve a descriptor will fail.
355 : #define DEFINE_NULL_CALL_INTERFACE_DESCRIPTOR() \
356 : public: \
357 : CallInterfaceDescriptor GetCallInterfaceDescriptor() const override { \
358 : UNREACHABLE(); \
359 : return CallInterfaceDescriptor(); \
360 : }
361 :
362 :
363 357668 : class PlatformCodeStub : public CodeStub {
364 : public:
365 : // Retrieve the code for the stub. Generate the code if needed.
366 : Handle<Code> GenerateCode() override;
367 :
368 : protected:
369 7064475 : explicit PlatformCodeStub(Isolate* isolate) : CodeStub(isolate) {}
370 :
371 : // Generates the assembler code for the stub.
372 : virtual void Generate(MacroAssembler* masm) = 0;
373 :
374 179 : DEFINE_CODE_STUB_BASE(PlatformCodeStub, CodeStub);
375 : };
376 :
377 :
378 : enum StubFunctionMode { NOT_JS_FUNCTION_STUB_MODE, JS_FUNCTION_STUB_MODE };
379 :
380 :
381 : class CodeStubDescriptor {
382 : public:
383 : explicit CodeStubDescriptor(CodeStub* stub);
384 :
385 : CodeStubDescriptor(Isolate* isolate, uint32_t stub_key);
386 :
387 : void Initialize(Address deoptimization_handler = NULL,
388 : int hint_stack_parameter_count = -1,
389 : StubFunctionMode function_mode = NOT_JS_FUNCTION_STUB_MODE);
390 : void Initialize(Register stack_parameter_count,
391 : Address deoptimization_handler = NULL,
392 : int hint_stack_parameter_count = -1,
393 : StubFunctionMode function_mode = NOT_JS_FUNCTION_STUB_MODE);
394 :
395 73400 : void SetMissHandler(Runtime::FunctionId id) {
396 73400 : miss_handler_id_ = id;
397 73400 : miss_handler_ = ExternalReference(Runtime::FunctionForId(id), isolate_);
398 73400 : has_miss_handler_ = true;
399 : // Our miss handler infrastructure doesn't currently support
400 : // variable stack parameter counts.
401 : DCHECK(!stack_parameter_count_.is_valid());
402 73400 : }
403 :
404 26647 : void set_call_descriptor(CallInterfaceDescriptor d) { call_descriptor_ = d; }
405 : CallInterfaceDescriptor call_descriptor() const { return call_descriptor_; }
406 :
407 : int GetRegisterParameterCount() const {
408 : return call_descriptor().GetRegisterParameterCount();
409 : }
410 :
411 : int GetStackParameterCount() const {
412 : return call_descriptor().GetStackParameterCount();
413 : }
414 :
415 : int GetParameterCount() const {
416 : return call_descriptor().GetParameterCount();
417 : }
418 :
419 : Register GetRegisterParameter(int index) const {
420 : return call_descriptor().GetRegisterParameter(index);
421 : }
422 :
423 : MachineType GetParameterType(int index) const {
424 : return call_descriptor().GetParameterType(index);
425 : }
426 :
427 : ExternalReference miss_handler() const {
428 : DCHECK(has_miss_handler_);
429 : return miss_handler_;
430 : }
431 :
432 : Runtime::FunctionId miss_handler_id() const {
433 : DCHECK(has_miss_handler_);
434 : return miss_handler_id_;
435 : }
436 :
437 : bool has_miss_handler() const {
438 : return has_miss_handler_;
439 : }
440 :
441 : int GetHandlerParameterCount() const {
442 : int params = GetParameterCount();
443 26647 : if (PassesArgumentsToDeoptimizationHandler()) {
444 0 : params += 1;
445 : }
446 : return params;
447 : }
448 :
449 : int hint_stack_parameter_count() const { return hint_stack_parameter_count_; }
450 : Register stack_parameter_count() const { return stack_parameter_count_; }
451 : StubFunctionMode function_mode() const { return function_mode_; }
452 : Address deoptimization_handler() const { return deoptimization_handler_; }
453 :
454 : private:
455 : bool PassesArgumentsToDeoptimizationHandler() const {
456 : return stack_parameter_count_.is_valid();
457 : }
458 :
459 : Isolate* isolate_;
460 : CallInterfaceDescriptor call_descriptor_;
461 : Register stack_parameter_count_;
462 : // If hint_stack_parameter_count_ > 0, the code stub can optimize the
463 : // return sequence. Default value is -1, which means it is ignored.
464 : int hint_stack_parameter_count_;
465 : StubFunctionMode function_mode_;
466 :
467 : Address deoptimization_handler_;
468 :
469 : ExternalReference miss_handler_;
470 : Runtime::FunctionId miss_handler_id_;
471 : bool has_miss_handler_;
472 : };
473 :
474 :
475 387899 : class HydrogenCodeStub : public CodeStub {
476 : public:
477 : enum InitializationState {
478 : UNINITIALIZED,
479 : INITIALIZED
480 : };
481 :
482 : template<class SubClass>
483 : static Handle<Code> GetUninitialized(Isolate* isolate) {
484 : SubClass::GenerateAheadOfTime(isolate);
485 : return SubClass().GetCode(isolate);
486 : }
487 :
488 : // Retrieve the code for the stub. Generate the code if needed.
489 : Handle<Code> GenerateCode() override = 0;
490 :
491 : bool IsUninitialized() const { return IsMissBits::decode(minor_key_); }
492 :
493 : Handle<Code> GenerateLightweightMissCode(ExternalReference miss);
494 :
495 : Handle<Code> GenerateRuntimeTailCall(CodeStubDescriptor* descriptor);
496 :
497 : template<class StateType>
498 : void TraceTransition(StateType from, StateType to);
499 :
500 : protected:
501 : explicit HydrogenCodeStub(Isolate* isolate,
502 : InitializationState state = INITIALIZED)
503 1592643 : : CodeStub(isolate) {
504 1066486 : minor_key_ = IsMissBits::encode(state == UNINITIALIZED);
505 : }
506 :
507 : void set_sub_minor_key(uint32_t key) {
508 2721466 : minor_key_ = SubMinorKeyBits::update(minor_key_, key);
509 : }
510 :
511 130747 : uint32_t sub_minor_key() const { return SubMinorKeyBits::decode(minor_key_); }
512 :
513 : static const int kSubMinorKeyBits = kStubMinorKeyBits - 1;
514 :
515 : private:
516 : class IsMissBits : public BitField<bool, kSubMinorKeyBits, 1> {};
517 : class SubMinorKeyBits : public BitField<int, 0, kSubMinorKeyBits> {};
518 :
519 : void GenerateLightweightMiss(MacroAssembler* masm, ExternalReference miss);
520 :
521 26671 : DEFINE_CODE_STUB_BASE(HydrogenCodeStub, CodeStub);
522 : };
523 :
524 :
525 269095 : class TurboFanCodeStub : public CodeStub {
526 : public:
527 : // Retrieve the code for the stub. Generate the code if needed.
528 : Handle<Code> GenerateCode() override;
529 :
530 0 : int GetStackParameterCount() const override {
531 0 : return GetCallInterfaceDescriptor().GetStackParameterCount();
532 : }
533 :
534 : protected:
535 2182310 : explicit TurboFanCodeStub(Isolate* isolate) : CodeStub(isolate) {}
536 :
537 : virtual void GenerateAssembly(compiler::CodeAssemblerState* state) const = 0;
538 :
539 : private:
540 78 : DEFINE_CODE_STUB_BASE(TurboFanCodeStub, CodeStub);
541 : };
542 :
543 :
544 : // Helper interface to prepare to/restore after making runtime calls.
545 : class RuntimeCallHelper {
546 : public:
547 0 : virtual ~RuntimeCallHelper() {}
548 :
549 : virtual void BeforeCall(MacroAssembler* masm) const = 0;
550 :
551 : virtual void AfterCall(MacroAssembler* masm) const = 0;
552 :
553 : protected:
554 64 : RuntimeCallHelper() {}
555 :
556 : private:
557 : DISALLOW_COPY_AND_ASSIGN(RuntimeCallHelper);
558 : };
559 :
560 :
561 : } // namespace internal
562 : } // namespace v8
563 :
564 : #if V8_TARGET_ARCH_IA32
565 : #include "src/ia32/code-stubs-ia32.h"
566 : #elif V8_TARGET_ARCH_X64
567 : #include "src/x64/code-stubs-x64.h"
568 : #elif V8_TARGET_ARCH_ARM64
569 : #include "src/arm64/code-stubs-arm64.h"
570 : #elif V8_TARGET_ARCH_ARM
571 : #include "src/arm/code-stubs-arm.h"
572 : #elif V8_TARGET_ARCH_PPC
573 : #include "src/ppc/code-stubs-ppc.h"
574 : #elif V8_TARGET_ARCH_MIPS
575 : #include "src/mips/code-stubs-mips.h"
576 : #elif V8_TARGET_ARCH_MIPS64
577 : #include "src/mips64/code-stubs-mips64.h"
578 : #elif V8_TARGET_ARCH_S390
579 : #include "src/s390/code-stubs-s390.h"
580 : #elif V8_TARGET_ARCH_X87
581 : #include "src/x87/code-stubs-x87.h"
582 : #else
583 : #error Unsupported target architecture.
584 : #endif
585 :
586 : namespace v8 {
587 : namespace internal {
588 :
589 :
590 : // RuntimeCallHelper implementation used in stubs: enters/leaves a
591 : // newly created internal frame before/after the runtime call.
592 0 : class StubRuntimeCallHelper : public RuntimeCallHelper {
593 : public:
594 : StubRuntimeCallHelper() {}
595 :
596 : void BeforeCall(MacroAssembler* masm) const override;
597 :
598 : void AfterCall(MacroAssembler* masm) const override;
599 : };
600 :
601 :
602 : // Trivial RuntimeCallHelper implementation.
603 0 : class NopRuntimeCallHelper : public RuntimeCallHelper {
604 : public:
605 64 : NopRuntimeCallHelper() {}
606 :
607 128 : void BeforeCall(MacroAssembler* masm) const override {}
608 :
609 128 : void AfterCall(MacroAssembler* masm) const override {}
610 : };
611 :
612 :
613 0 : class StringLengthStub : public TurboFanCodeStub {
614 : public:
615 248 : explicit StringLengthStub(Isolate* isolate) : TurboFanCodeStub(isolate) {}
616 :
617 76 : Code::Kind GetCodeKind() const override { return Code::HANDLER; }
618 76 : ExtraICState GetExtraICState() const override { return Code::LOAD_IC; }
619 :
620 166 : DEFINE_CALL_INTERFACE_DESCRIPTOR(LoadWithVector);
621 531 : DEFINE_TURBOFAN_CODE_STUB(StringLength, TurboFanCodeStub);
622 : };
623 :
624 0 : class StoreInterceptorStub : public TurboFanCodeStub {
625 : public:
626 153 : explicit StoreInterceptorStub(Isolate* isolate) : TurboFanCodeStub(isolate) {}
627 :
628 98 : Code::Kind GetCodeKind() const override { return Code::HANDLER; }
629 98 : ExtraICState GetExtraICState() const override { return Code::STORE_IC; }
630 :
631 196 : DEFINE_CALL_INTERFACE_DESCRIPTOR(StoreWithVector);
632 545 : DEFINE_TURBOFAN_CODE_STUB(StoreInterceptor, TurboFanCodeStub);
633 : };
634 :
635 0 : class LoadIndexedInterceptorStub : public TurboFanCodeStub {
636 : public:
637 : explicit LoadIndexedInterceptorStub(Isolate* isolate)
638 97 : : TurboFanCodeStub(isolate) {}
639 :
640 68 : Code::Kind GetCodeKind() const override { return Code::HANDLER; }
641 68 : ExtraICState GetExtraICState() const override { return Code::KEYED_LOAD_IC; }
642 :
643 136 : DEFINE_CALL_INTERFACE_DESCRIPTOR(LoadWithVector);
644 369 : DEFINE_TURBOFAN_CODE_STUB(LoadIndexedInterceptor, TurboFanCodeStub);
645 : };
646 :
647 : // ES6 [[Get]] operation.
648 43 : class GetPropertyStub : public TurboFanCodeStub {
649 : public:
650 3232 : explicit GetPropertyStub(Isolate* isolate) : TurboFanCodeStub(isolate) {}
651 :
652 172 : DEFINE_CALL_INTERFACE_DESCRIPTOR(GetProperty);
653 3404 : DEFINE_TURBOFAN_CODE_STUB(GetProperty, TurboFanCodeStub);
654 : };
655 :
656 0 : class NumberToStringStub final : public TurboFanCodeStub {
657 : public:
658 430 : explicit NumberToStringStub(Isolate* isolate) : TurboFanCodeStub(isolate) {}
659 :
660 86 : DEFINE_CALL_INTERFACE_DESCRIPTOR(TypeConversion);
661 602 : DEFINE_TURBOFAN_CODE_STUB(NumberToString, TurboFanCodeStub);
662 : };
663 :
664 0 : class CreateAllocationSiteStub : public TurboFanCodeStub {
665 : public:
666 : explicit CreateAllocationSiteStub(Isolate* isolate)
667 4653 : : TurboFanCodeStub(isolate) {}
668 : static void GenerateAheadOfTime(Isolate* isolate);
669 :
670 86 : DEFINE_CALL_INTERFACE_DESCRIPTOR(CreateAllocationSite);
671 4825 : DEFINE_TURBOFAN_CODE_STUB(CreateAllocationSite, TurboFanCodeStub);
672 : };
673 :
674 0 : class CreateWeakCellStub : public TurboFanCodeStub {
675 : public:
676 4653 : explicit CreateWeakCellStub(Isolate* isolate) : TurboFanCodeStub(isolate) {}
677 :
678 : static void GenerateAheadOfTime(Isolate* isolate);
679 :
680 86 : DEFINE_CALL_INTERFACE_DESCRIPTOR(CreateWeakCell);
681 4825 : DEFINE_TURBOFAN_CODE_STUB(CreateWeakCell, TurboFanCodeStub);
682 : };
683 :
684 2539 : class GrowArrayElementsStub : public TurboFanCodeStub {
685 : public:
686 : GrowArrayElementsStub(Isolate* isolate, ElementsKind kind)
687 2539 : : TurboFanCodeStub(isolate) {
688 2539 : minor_key_ = ElementsKindBits::encode(GetHoleyElementsKind(kind));
689 : }
690 :
691 : ElementsKind elements_kind() const {
692 : return ElementsKindBits::decode(minor_key_);
693 : }
694 :
695 : private:
696 : class ElementsKindBits : public BitField<ElementsKind, 0, 8> {};
697 :
698 618 : DEFINE_CALL_INTERFACE_DESCRIPTOR(GrowArrayElements);
699 3775 : DEFINE_TURBOFAN_CODE_STUB(GrowArrayElements, TurboFanCodeStub);
700 : };
701 :
702 : enum AllocationSiteOverrideMode {
703 : DONT_OVERRIDE,
704 : DISABLE_ALLOCATION_SITES,
705 : LAST_ALLOCATION_SITE_OVERRIDE_MODE = DISABLE_ALLOCATION_SITES
706 : };
707 :
708 :
709 79 : class ArrayConstructorStub: public PlatformCodeStub {
710 : public:
711 : explicit ArrayConstructorStub(Isolate* isolate);
712 :
713 : private:
714 : void GenerateDispatchToArrayStub(MacroAssembler* masm,
715 : AllocationSiteOverrideMode mode);
716 :
717 0 : DEFINE_CALL_INTERFACE_DESCRIPTOR(ArrayConstructor);
718 28442 : DEFINE_PLATFORM_CODE_STUB(ArrayConstructor, PlatformCodeStub);
719 : };
720 :
721 :
722 0 : class InternalArrayConstructorStub: public PlatformCodeStub {
723 : public:
724 : explicit InternalArrayConstructorStub(Isolate* isolate);
725 :
726 : private:
727 : void GenerateCase(MacroAssembler* masm, ElementsKind kind);
728 :
729 0 : DEFINE_CALL_INTERFACE_DESCRIPTOR(ArrayNArgumentsConstructor);
730 409 : DEFINE_PLATFORM_CODE_STUB(InternalArrayConstructor, PlatformCodeStub);
731 : };
732 :
733 :
734 0 : class MathPowStub: public PlatformCodeStub {
735 : public:
736 : enum ExponentType { INTEGER, DOUBLE, TAGGED };
737 :
738 : MathPowStub(Isolate* isolate, ExponentType exponent_type)
739 932 : : PlatformCodeStub(isolate) {
740 572 : minor_key_ = ExponentTypeBits::encode(exponent_type);
741 : }
742 :
743 0 : CallInterfaceDescriptor GetCallInterfaceDescriptor() const override {
744 0 : if (exponent_type() == TAGGED) {
745 0 : return MathPowTaggedDescriptor(isolate());
746 0 : } else if (exponent_type() == INTEGER) {
747 0 : return MathPowIntegerDescriptor(isolate());
748 : } else {
749 : // A CallInterfaceDescriptor doesn't specify double registers (yet).
750 : DCHECK_EQ(DOUBLE, exponent_type());
751 0 : return ContextOnlyDescriptor(isolate());
752 : }
753 : }
754 :
755 : private:
756 : ExponentType exponent_type() const {
757 : return ExponentTypeBits::decode(minor_key_);
758 : }
759 :
760 : class ExponentTypeBits : public BitField<ExponentType, 0, 2> {};
761 :
762 1268 : DEFINE_PLATFORM_CODE_STUB(MathPow, PlatformCodeStub);
763 : };
764 :
765 0 : class CallICStub : public TurboFanCodeStub {
766 : public:
767 : CallICStub(Isolate* isolate, ConvertReceiverMode convert_mode,
768 : TailCallMode tail_call_mode)
769 1733854 : : TurboFanCodeStub(isolate) {
770 1733854 : minor_key_ = ConvertModeBits::encode(convert_mode) |
771 1733854 : TailCallModeBits::encode(tail_call_mode);
772 : }
773 :
774 : ConvertReceiverMode convert_mode() const {
775 : return ConvertModeBits::decode(minor_key_);
776 : }
777 : TailCallMode tail_call_mode() const {
778 : return TailCallModeBits::decode(minor_key_);
779 : }
780 :
781 : protected:
782 : typedef BitField<ConvertReceiverMode, 0, 2> ConvertModeBits;
783 : typedef BitField<TailCallMode, ConvertModeBits::kNext, 1> TailCallModeBits;
784 :
785 : private:
786 : void PrintState(std::ostream& os) const final; // NOLINT
787 :
788 56296 : DEFINE_CALL_INTERFACE_DESCRIPTOR(CallIC);
789 741151 : DEFINE_TURBOFAN_CODE_STUB(CallIC, TurboFanCodeStub);
790 : };
791 :
792 0 : class KeyedLoadSloppyArgumentsStub : public TurboFanCodeStub {
793 : public:
794 : explicit KeyedLoadSloppyArgumentsStub(Isolate* isolate)
795 3189 : : TurboFanCodeStub(isolate) {}
796 :
797 350 : Code::Kind GetCodeKind() const override { return Code::HANDLER; }
798 350 : ExtraICState GetExtraICState() const override { return Code::LOAD_IC; }
799 :
800 : protected:
801 700 : DEFINE_CALL_INTERFACE_DESCRIPTOR(LoadWithVector);
802 4589 : DEFINE_TURBOFAN_CODE_STUB(KeyedLoadSloppyArguments, TurboFanCodeStub);
803 : };
804 :
805 :
806 : class CommonStoreModeBits : public BitField<KeyedAccessStoreMode, 0, 3> {};
807 :
808 0 : class KeyedStoreSloppyArgumentsStub : public TurboFanCodeStub {
809 : public:
810 : explicit KeyedStoreSloppyArgumentsStub(Isolate* isolate,
811 : KeyedAccessStoreMode mode)
812 0 : : TurboFanCodeStub(isolate) {
813 0 : minor_key_ = CommonStoreModeBits::encode(mode);
814 : }
815 :
816 0 : Code::Kind GetCodeKind() const override { return Code::HANDLER; }
817 0 : ExtraICState GetExtraICState() const override { return Code::STORE_IC; }
818 :
819 : protected:
820 0 : DEFINE_CALL_INTERFACE_DESCRIPTOR(StoreWithVector);
821 0 : DEFINE_TURBOFAN_CODE_STUB(KeyedStoreSloppyArguments, TurboFanCodeStub);
822 : };
823 :
824 11206 : class CallApiCallbackStub : public PlatformCodeStub {
825 : public:
826 : static const int kArgBits = 3;
827 : static const int kArgMax = (1 << kArgBits) - 1;
828 :
829 : // CallApiCallbackStub for regular setters and getters.
830 : CallApiCallbackStub(Isolate* isolate, bool is_store, bool is_lazy)
831 393 : : CallApiCallbackStub(isolate, is_store ? 1 : 0, is_store, is_lazy) {}
832 :
833 : // CallApiCallbackStub for callback functions.
834 : CallApiCallbackStub(Isolate* isolate, int argc, bool is_lazy)
835 20157 : : CallApiCallbackStub(isolate, argc, false, is_lazy) {}
836 :
837 : private:
838 20550 : CallApiCallbackStub(Isolate* isolate, int argc, bool is_store, bool is_lazy)
839 20550 : : PlatformCodeStub(isolate) {
840 20550 : CHECK(0 <= argc && argc <= kArgMax);
841 20550 : minor_key_ = IsStoreBits::encode(is_store) |
842 20550 : ArgumentBits::encode(argc) |
843 20550 : IsLazyAccessorBits::encode(is_lazy);
844 20550 : }
845 :
846 : bool is_store() const { return IsStoreBits::decode(minor_key_); }
847 : bool is_lazy() const { return IsLazyAccessorBits::decode(minor_key_); }
848 : int argc() const { return ArgumentBits::decode(minor_key_); }
849 :
850 : class IsStoreBits: public BitField<bool, 0, 1> {};
851 : class IsLazyAccessorBits : public BitField<bool, 1, 1> {};
852 : class ArgumentBits : public BitField<int, 2, kArgBits> {};
853 :
854 40406 : DEFINE_CALL_INTERFACE_DESCRIPTOR(ApiCallback);
855 38943 : DEFINE_PLATFORM_CODE_STUB(CallApiCallback, PlatformCodeStub);
856 : };
857 :
858 :
859 0 : class CallApiGetterStub : public PlatformCodeStub {
860 : public:
861 1591 : explicit CallApiGetterStub(Isolate* isolate) : PlatformCodeStub(isolate) {}
862 :
863 0 : DEFINE_CALL_INTERFACE_DESCRIPTOR(ApiGetter);
864 1720 : DEFINE_PLATFORM_CODE_STUB(CallApiGetter, PlatformCodeStub);
865 : };
866 :
867 :
868 387497 : class BinaryOpICStub : public HydrogenCodeStub {
869 : public:
870 834777 : BinaryOpICStub(Isolate* isolate, Token::Value op)
871 834777 : : HydrogenCodeStub(isolate, UNINITIALIZED) {
872 : BinaryOpICState state(isolate, op);
873 834777 : set_sub_minor_key(state.GetExtraICState());
874 834777 : }
875 :
876 : BinaryOpICStub(Isolate* isolate, const BinaryOpICState& state)
877 395062 : : HydrogenCodeStub(isolate) {
878 395062 : set_sub_minor_key(state.GetExtraICState());
879 : }
880 :
881 : static void GenerateAheadOfTime(Isolate* isolate);
882 :
883 6372 : Code::Kind GetCodeKind() const override { return Code::BINARY_OP_IC; }
884 :
885 10239 : ExtraICState GetExtraICState() const final {
886 40440 : return static_cast<ExtraICState>(sub_minor_key());
887 : }
888 :
889 : BinaryOpICState state() const {
890 19962 : return BinaryOpICState(isolate(), GetExtraICState());
891 : }
892 :
893 : void PrintState(std::ostream& os) const final; // NOLINT
894 :
895 : private:
896 : static void GenerateAheadOfTime(Isolate* isolate,
897 : const BinaryOpICState& state);
898 :
899 68896 : DEFINE_CALL_INTERFACE_DESCRIPTOR(BinaryOp);
900 1267293 : DEFINE_HYDROGEN_CODE_STUB(BinaryOpIC, HydrogenCodeStub);
901 : };
902 :
903 :
904 : // TODO(bmeurer): Merge this into the BinaryOpICStub once we have proper tail
905 : // call support for stubs in Hydrogen.
906 46824 : class BinaryOpICWithAllocationSiteStub final : public PlatformCodeStub {
907 : public:
908 : BinaryOpICWithAllocationSiteStub(Isolate* isolate,
909 : const BinaryOpICState& state)
910 46824 : : PlatformCodeStub(isolate) {
911 46824 : minor_key_ = state.GetExtraICState();
912 : }
913 :
914 : static void GenerateAheadOfTime(Isolate* isolate);
915 :
916 46824 : Handle<Code> GetCodeCopyFromTemplate(Handle<AllocationSite> allocation_site) {
917 : FindAndReplacePattern pattern;
918 46824 : pattern.Add(isolate()->factory()->undefined_map(), allocation_site);
919 46824 : return CodeStub::GetCodeCopy(pattern);
920 : }
921 :
922 3867 : Code::Kind GetCodeKind() const override { return Code::BINARY_OP_IC; }
923 :
924 3867 : ExtraICState GetExtraICState() const override {
925 58425 : return static_cast<ExtraICState>(minor_key_);
926 : }
927 :
928 : void PrintState(std::ostream& os) const override; // NOLINT
929 :
930 : private:
931 : BinaryOpICState state() const {
932 54558 : return BinaryOpICState(isolate(), GetExtraICState());
933 : }
934 :
935 : static void GenerateAheadOfTime(Isolate* isolate,
936 : const BinaryOpICState& state);
937 :
938 0 : DEFINE_CALL_INTERFACE_DESCRIPTOR(BinaryOpWithAllocationSite);
939 105249 : DEFINE_PLATFORM_CODE_STUB(BinaryOpICWithAllocationSite, PlatformCodeStub);
940 : };
941 :
942 :
943 0 : class BinaryOpWithAllocationSiteStub final : public BinaryOpICStub {
944 : public:
945 : BinaryOpWithAllocationSiteStub(Isolate* isolate, Token::Value op)
946 : : BinaryOpICStub(isolate, op) {}
947 :
948 : BinaryOpWithAllocationSiteStub(Isolate* isolate, const BinaryOpICState& state)
949 3867 : : BinaryOpICStub(isolate, state) {}
950 :
951 3867 : Code::Kind GetCodeKind() const final { return Code::STUB; }
952 :
953 24124 : DEFINE_CALL_INTERFACE_DESCRIPTOR(BinaryOpWithAllocationSite);
954 15929 : DEFINE_HYDROGEN_CODE_STUB(BinaryOpWithAllocationSite, BinaryOpICStub);
955 : };
956 :
957 0 : class StringAddStub final : public TurboFanCodeStub {
958 : public:
959 : StringAddStub(Isolate* isolate, StringAddFlags flags,
960 : PretenureFlag pretenure_flag)
961 92531 : : TurboFanCodeStub(isolate) {
962 92531 : minor_key_ = (StringAddFlagsBits::encode(flags) |
963 92531 : PretenureFlagBits::encode(pretenure_flag));
964 : }
965 :
966 : StringAddFlags flags() const {
967 : return StringAddFlagsBits::decode(minor_key_);
968 : }
969 :
970 : PretenureFlag pretenure_flag() const {
971 : return PretenureFlagBits::decode(minor_key_);
972 : }
973 :
974 : private:
975 : class StringAddFlagsBits : public BitField<StringAddFlags, 0, 3> {};
976 : class PretenureFlagBits : public BitField<PretenureFlag, 3, 1> {};
977 :
978 : void PrintBaseName(std::ostream& os) const override; // NOLINT
979 :
980 258 : DEFINE_CALL_INTERFACE_DESCRIPTOR(StringAdd);
981 92918 : DEFINE_TURBOFAN_CODE_STUB(StringAdd, TurboFanCodeStub);
982 : };
983 :
984 :
985 272912 : class CompareICStub : public PlatformCodeStub {
986 : public:
987 : CompareICStub(Isolate* isolate, Token::Value op, CompareICState::State left,
988 : CompareICState::State right, CompareICState::State state)
989 988817 : : PlatformCodeStub(isolate) {
990 : DCHECK(Token::IsCompareOp(op));
991 : DCHECK(OpBits::is_valid(op - Token::EQ));
992 1258305 : minor_key_ = OpBits::encode(op - Token::EQ) |
993 549248 : LeftStateBits::encode(left) | RightStateBits::encode(right) |
994 988817 : StateBits::encode(state);
995 : }
996 : // Creates uninitialized compare stub.
997 : CompareICStub(Isolate* isolate, Token::Value op)
998 : : CompareICStub(isolate, op, CompareICState::UNINITIALIZED,
999 : CompareICState::UNINITIALIZED,
1000 : CompareICState::UNINITIALIZED) {}
1001 :
1002 : CompareICStub(Isolate* isolate, ExtraICState extra_ic_state)
1003 818740 : : PlatformCodeStub(isolate) {
1004 818740 : minor_key_ = extra_ic_state;
1005 : }
1006 :
1007 66854 : ExtraICState GetExtraICState() const final {
1008 66854 : return static_cast<ExtraICState>(minor_key_);
1009 : }
1010 :
1011 2159 : void set_known_map(Handle<Map> map) { known_map_ = map; }
1012 :
1013 : InlineCacheState GetICState() const;
1014 :
1015 : Token::Value op() const {
1016 146357 : return static_cast<Token::Value>(Token::EQ + OpBits::decode(minor_key_));
1017 : }
1018 :
1019 : CompareICState::State left() const {
1020 : return LeftStateBits::decode(minor_key_);
1021 : }
1022 : CompareICState::State right() const {
1023 : return RightStateBits::decode(minor_key_);
1024 : }
1025 : CompareICState::State state() const { return StateBits::decode(minor_key_); }
1026 :
1027 : private:
1028 66854 : Code::Kind GetCodeKind() const override { return Code::COMPARE_IC; }
1029 :
1030 : void GenerateBooleans(MacroAssembler* masm);
1031 : void GenerateSmis(MacroAssembler* masm);
1032 : void GenerateNumbers(MacroAssembler* masm);
1033 : void GenerateInternalizedStrings(MacroAssembler* masm);
1034 : void GenerateStrings(MacroAssembler* masm);
1035 : void GenerateUniqueNames(MacroAssembler* masm);
1036 : void GenerateReceivers(MacroAssembler* masm);
1037 : void GenerateMiss(MacroAssembler* masm);
1038 : void GenerateKnownReceivers(MacroAssembler* masm);
1039 : void GenerateGeneric(MacroAssembler* masm);
1040 :
1041 36258 : bool strict() const { return op() == Token::EQ_STRICT; }
1042 : Condition GetCondition() const;
1043 :
1044 : // Although we don't cache anything in the special cache we have to define
1045 : // this predicate to avoid appearance of code stubs with embedded maps in
1046 : // the global stub cache.
1047 1055692 : bool UseSpecialCache() override {
1048 1055692 : return state() == CompareICState::KNOWN_RECEIVER;
1049 : }
1050 :
1051 : class OpBits : public BitField<int, 0, 3> {};
1052 : class LeftStateBits : public BitField<CompareICState::State, 3, 4> {};
1053 : class RightStateBits : public BitField<CompareICState::State, 7, 4> {};
1054 : class StateBits : public BitField<CompareICState::State, 11, 4> {};
1055 :
1056 : Handle<Map> known_map_;
1057 :
1058 0 : DEFINE_CALL_INTERFACE_DESCRIPTOR(BinaryOp);
1059 1185084 : DEFINE_PLATFORM_CODE_STUB(CompareIC, PlatformCodeStub);
1060 : };
1061 :
1062 :
1063 0 : class CEntryStub : public PlatformCodeStub {
1064 : public:
1065 : CEntryStub(Isolate* isolate, int result_size,
1066 : SaveFPRegsMode save_doubles = kDontSaveFPRegs,
1067 : ArgvMode argv_mode = kArgvOnStack, bool builtin_exit_frame = false)
1068 3459629 : : PlatformCodeStub(isolate) {
1069 4505422 : minor_key_ = SaveDoublesBits::encode(save_doubles == kSaveFPRegs) |
1070 1247487 : FrameTypeBits::encode(builtin_exit_frame) |
1071 4545164 : ArgvMode::encode(argv_mode == kArgvInRegister);
1072 : DCHECK(result_size == 1 || result_size == 2 || result_size == 3);
1073 3459629 : minor_key_ = ResultSizeBits::update(minor_key_, result_size);
1074 : }
1075 :
1076 : // The version of this stub that doesn't save doubles is generated ahead of
1077 : // time, so it's OK to call it from other stubs that can't cope with GC during
1078 : // their code generation. On machines that always have gp registers (x64) we
1079 : // can generate both variants ahead of time.
1080 : static void GenerateAheadOfTime(Isolate* isolate);
1081 :
1082 : private:
1083 : bool save_doubles() const { return SaveDoublesBits::decode(minor_key_); }
1084 : bool argv_in_register() const { return ArgvMode::decode(minor_key_); }
1085 : bool is_builtin_exit() const { return FrameTypeBits::decode(minor_key_); }
1086 : int result_size() const { return ResultSizeBits::decode(minor_key_); }
1087 :
1088 : bool NeedsImmovableCode() override;
1089 :
1090 : class SaveDoublesBits : public BitField<bool, 0, 1> {};
1091 : class ArgvMode : public BitField<bool, 1, 1> {};
1092 : class FrameTypeBits : public BitField<bool, 2, 1> {};
1093 : class ResultSizeBits : public BitField<int, 3, 3> {};
1094 :
1095 0 : DEFINE_NULL_CALL_INTERFACE_DESCRIPTOR();
1096 3114404 : DEFINE_PLATFORM_CODE_STUB(CEntry, PlatformCodeStub);
1097 : };
1098 :
1099 :
1100 0 : class JSEntryStub : public PlatformCodeStub {
1101 : public:
1102 : JSEntryStub(Isolate* isolate, StackFrame::Type type)
1103 86 : : PlatformCodeStub(isolate) {
1104 : DCHECK(type == StackFrame::ENTRY || type == StackFrame::ENTRY_CONSTRUCT);
1105 86 : minor_key_ = StackFrameTypeBits::encode(type);
1106 : }
1107 :
1108 : private:
1109 : void FinishCode(Handle<Code> code) override;
1110 :
1111 86 : void PrintName(std::ostream& os) const override { // NOLINT
1112 : os << (type() == StackFrame::ENTRY ? "JSEntryStub"
1113 86 : : "JSConstructEntryStub");
1114 86 : }
1115 :
1116 : StackFrame::Type type() const {
1117 : return StackFrameTypeBits::decode(minor_key_);
1118 : }
1119 :
1120 : class StackFrameTypeBits : public BitField<StackFrame::Type, 0, 5> {};
1121 :
1122 : int handler_offset_;
1123 :
1124 0 : DEFINE_NULL_CALL_INTERFACE_DESCRIPTOR();
1125 258 : DEFINE_PLATFORM_CODE_STUB(JSEntry, PlatformCodeStub);
1126 : };
1127 :
1128 : // TODO(bmeurer/mvstanton): Turn CallConstructStub into ConstructICStub.
1129 0 : class CallConstructStub final : public PlatformCodeStub {
1130 : public:
1131 123776 : explicit CallConstructStub(Isolate* isolate) : PlatformCodeStub(isolate) {}
1132 :
1133 0 : DEFINE_CALL_INTERFACE_DESCRIPTOR(CallConstruct);
1134 137610 : DEFINE_PLATFORM_CODE_STUB(CallConstruct, PlatformCodeStub);
1135 : };
1136 :
1137 :
1138 : enum ReceiverCheckMode {
1139 : // We don't know anything about the receiver.
1140 : RECEIVER_IS_UNKNOWN,
1141 :
1142 : // We know the receiver is a string.
1143 : RECEIVER_IS_STRING
1144 : };
1145 :
1146 :
1147 : enum EmbedMode {
1148 : // The code being generated is part of an IC handler, which may MISS
1149 : // to an IC in failure cases.
1150 : PART_OF_IC_HANDLER,
1151 :
1152 : NOT_PART_OF_IC_HANDLER
1153 : };
1154 :
1155 :
1156 : // Generates code implementing String.prototype.charCodeAt.
1157 : //
1158 : // Only supports the case when the receiver is a string and the index
1159 : // is a number (smi or heap number) that is a valid index into the
1160 : // string. Additional index constraints are specified by the
1161 : // flags. Otherwise, bails out to the provided labels.
1162 : //
1163 : // Register usage: |object| may be changed to another string in a way
1164 : // that doesn't affect charCodeAt/charAt semantics, |index| is
1165 : // preserved, |scratch| and |result| are clobbered.
1166 : class StringCharCodeAtGenerator {
1167 : public:
1168 : StringCharCodeAtGenerator(Register object, Register index, Register result,
1169 : Label* receiver_not_string, Label* index_not_number,
1170 : Label* index_out_of_range,
1171 : ReceiverCheckMode check_mode = RECEIVER_IS_UNKNOWN)
1172 : : object_(object),
1173 : index_(index),
1174 : result_(result),
1175 : receiver_not_string_(receiver_not_string),
1176 : index_not_number_(index_not_number),
1177 : index_out_of_range_(index_out_of_range),
1178 64 : check_mode_(check_mode) {
1179 : DCHECK(!result_.is(object_));
1180 : DCHECK(!result_.is(index_));
1181 : }
1182 :
1183 : // Generates the fast case code. On the fallthrough path |result|
1184 : // register contains the result.
1185 : void GenerateFast(MacroAssembler* masm);
1186 :
1187 : // Generates the slow case code. Must not be naturally
1188 : // reachable. Expected to be put after a ret instruction (e.g., in
1189 : // deferred code). Always jumps back to the fast case.
1190 : void GenerateSlow(MacroAssembler* masm, EmbedMode embed_mode,
1191 : const RuntimeCallHelper& call_helper);
1192 :
1193 : private:
1194 : Register object_;
1195 : Register index_;
1196 : Register result_;
1197 :
1198 : Label* receiver_not_string_;
1199 : Label* index_not_number_;
1200 : Label* index_out_of_range_;
1201 :
1202 : ReceiverCheckMode check_mode_;
1203 :
1204 : Label call_runtime_;
1205 : Label index_not_smi_;
1206 : Label got_smi_index_;
1207 : Label exit_;
1208 :
1209 : DISALLOW_COPY_AND_ASSIGN(StringCharCodeAtGenerator);
1210 : };
1211 :
1212 0 : class CallICTrampolineStub : public CallICStub {
1213 : public:
1214 : CallICTrampolineStub(Isolate* isolate, ConvertReceiverMode convert_mode,
1215 : TailCallMode tail_call_mode)
1216 1105373 : : CallICStub(isolate, convert_mode, tail_call_mode) {}
1217 :
1218 52320 : DEFINE_CALL_INTERFACE_DESCRIPTOR(CallICTrampoline);
1219 1210172 : DEFINE_TURBOFAN_CODE_STUB(CallICTrampoline, CallICStub);
1220 : };
1221 :
1222 0 : class DoubleToIStub : public PlatformCodeStub {
1223 : public:
1224 : DoubleToIStub(Isolate* isolate, Register source, Register destination,
1225 : int offset, bool is_truncating, bool skip_fastpath = false)
1226 93526 : : PlatformCodeStub(isolate) {
1227 93526 : minor_key_ = SourceRegisterBits::encode(source.code()) |
1228 93526 : DestinationRegisterBits::encode(destination.code()) |
1229 93526 : OffsetBits::encode(offset) |
1230 : IsTruncatingBits::encode(is_truncating) |
1231 93526 : SkipFastPathBits::encode(skip_fastpath) |
1232 187052 : SSE3Bits::encode(CpuFeatures::IsSupported(SSE3) ? 1 : 0);
1233 : }
1234 :
1235 0 : bool SometimesSetsUpAFrame() override { return false; }
1236 :
1237 : private:
1238 : Register source() const {
1239 : return Register::from_code(SourceRegisterBits::decode(minor_key_));
1240 : }
1241 : Register destination() const {
1242 : return Register::from_code(DestinationRegisterBits::decode(minor_key_));
1243 : }
1244 : bool is_truncating() const { return IsTruncatingBits::decode(minor_key_); }
1245 : bool skip_fastpath() const { return SkipFastPathBits::decode(minor_key_); }
1246 : int offset() const { return OffsetBits::decode(minor_key_); }
1247 :
1248 : static const int kBitsPerRegisterNumber = 6;
1249 : STATIC_ASSERT((1L << kBitsPerRegisterNumber) >= Register::kNumRegisters);
1250 : class SourceRegisterBits:
1251 : public BitField<int, 0, kBitsPerRegisterNumber> {}; // NOLINT
1252 : class DestinationRegisterBits:
1253 : public BitField<int, kBitsPerRegisterNumber,
1254 : kBitsPerRegisterNumber> {}; // NOLINT
1255 : class IsTruncatingBits:
1256 : public BitField<bool, 2 * kBitsPerRegisterNumber, 1> {}; // NOLINT
1257 : class OffsetBits:
1258 : public BitField<int, 2 * kBitsPerRegisterNumber + 1, 3> {}; // NOLINT
1259 : class SkipFastPathBits:
1260 : public BitField<int, 2 * kBitsPerRegisterNumber + 4, 1> {}; // NOLINT
1261 : class SSE3Bits:
1262 : public BitField<int, 2 * kBitsPerRegisterNumber + 5, 1> {}; // NOLINT
1263 :
1264 0 : DEFINE_NULL_CALL_INTERFACE_DESCRIPTOR();
1265 121356 : DEFINE_PLATFORM_CODE_STUB(DoubleToI, PlatformCodeStub);
1266 : };
1267 :
1268 40 : class ScriptContextFieldStub : public TurboFanCodeStub {
1269 : public:
1270 : ScriptContextFieldStub(Isolate* isolate,
1271 : const ScriptContextTable::LookupResult* lookup_result)
1272 55496 : : TurboFanCodeStub(isolate) {
1273 : DCHECK(Accepted(lookup_result));
1274 110992 : minor_key_ = ContextIndexBits::encode(lookup_result->context_index) |
1275 110992 : SlotIndexBits::encode(lookup_result->slot_index);
1276 : }
1277 :
1278 13544 : Code::Kind GetCodeKind() const override { return Code::HANDLER; }
1279 :
1280 : int context_index() const { return ContextIndexBits::decode(minor_key_); }
1281 :
1282 : int slot_index() const { return SlotIndexBits::decode(minor_key_); }
1283 :
1284 : static bool Accepted(const ScriptContextTable::LookupResult* lookup_result) {
1285 166488 : return ContextIndexBits::is_valid(lookup_result->context_index) &&
1286 55496 : SlotIndexBits::is_valid(lookup_result->slot_index);
1287 : }
1288 :
1289 : private:
1290 : static const int kContextIndexBits = 9;
1291 : static const int kSlotIndexBits = 12;
1292 : class ContextIndexBits : public BitField<int, 0, kContextIndexBits> {};
1293 : class SlotIndexBits
1294 : : public BitField<int, kContextIndexBits, kSlotIndexBits> {};
1295 :
1296 0 : DEFINE_CODE_STUB_BASE(ScriptContextFieldStub, TurboFanCodeStub);
1297 : };
1298 :
1299 :
1300 0 : class LoadScriptContextFieldStub : public ScriptContextFieldStub {
1301 : public:
1302 : LoadScriptContextFieldStub(
1303 : Isolate* isolate, const ScriptContextTable::LookupResult* lookup_result)
1304 55456 : : ScriptContextFieldStub(isolate, lookup_result) {}
1305 :
1306 14961 : ExtraICState GetExtraICState() const override { return Code::LOAD_IC; }
1307 :
1308 : private:
1309 29922 : DEFINE_CALL_INTERFACE_DESCRIPTOR(LoadWithVector);
1310 115300 : DEFINE_TURBOFAN_CODE_STUB(LoadScriptContextField, ScriptContextFieldStub);
1311 : };
1312 :
1313 :
1314 40 : class StoreScriptContextFieldStub : public ScriptContextFieldStub {
1315 : public:
1316 : StoreScriptContextFieldStub(
1317 : Isolate* isolate, const ScriptContextTable::LookupResult* lookup_result)
1318 40 : : ScriptContextFieldStub(isolate, lookup_result) {}
1319 :
1320 31 : ExtraICState GetExtraICState() const override { return Code::STORE_IC; }
1321 :
1322 : private:
1323 62 : DEFINE_CALL_INTERFACE_DESCRIPTOR(StoreWithVector);
1324 164 : DEFINE_TURBOFAN_CODE_STUB(StoreScriptContextField, ScriptContextFieldStub);
1325 : };
1326 :
1327 254068 : class StoreFastElementStub : public TurboFanCodeStub {
1328 : public:
1329 : StoreFastElementStub(Isolate* isolate, bool is_js_array,
1330 : ElementsKind elements_kind, KeyedAccessStoreMode mode)
1331 254068 : : TurboFanCodeStub(isolate) {
1332 253466 : minor_key_ = CommonStoreModeBits::encode(mode) |
1333 253982 : ElementsKindBits::encode(elements_kind) |
1334 254068 : IsJSArrayBits::encode(is_js_array);
1335 : }
1336 :
1337 : static void GenerateAheadOfTime(Isolate* isolate);
1338 :
1339 : bool is_js_array() const { return IsJSArrayBits::decode(minor_key_); }
1340 :
1341 : ElementsKind elements_kind() const {
1342 : return ElementsKindBits::decode(minor_key_);
1343 : }
1344 :
1345 : KeyedAccessStoreMode store_mode() const {
1346 : return CommonStoreModeBits::decode(minor_key_);
1347 : }
1348 :
1349 3844 : Code::Kind GetCodeKind() const override { return Code::HANDLER; }
1350 3844 : ExtraICState GetExtraICState() const override { return Code::KEYED_STORE_IC; }
1351 :
1352 : private:
1353 : class ElementsKindBits
1354 : : public BitField<ElementsKind, CommonStoreModeBits::kNext, 8> {};
1355 : class IsJSArrayBits : public BitField<bool, ElementsKindBits::kNext, 1> {};
1356 :
1357 7688 : DEFINE_CALL_INTERFACE_DESCRIPTOR(StoreWithVector);
1358 269444 : DEFINE_TURBOFAN_CODE_STUB(StoreFastElement, TurboFanCodeStub);
1359 : };
1360 :
1361 :
1362 402 : class TransitionElementsKindStub : public HydrogenCodeStub {
1363 : public:
1364 : TransitionElementsKindStub(Isolate* isolate, ElementsKind from_kind,
1365 : ElementsKind to_kind)
1366 402 : : HydrogenCodeStub(isolate) {
1367 : set_sub_minor_key(FromKindBits::encode(from_kind) |
1368 402 : ToKindBits::encode(to_kind));
1369 : }
1370 :
1371 : ElementsKind from_kind() const {
1372 54 : return FromKindBits::decode(sub_minor_key());
1373 : }
1374 :
1375 : ElementsKind to_kind() const { return ToKindBits::decode(sub_minor_key()); }
1376 :
1377 : private:
1378 : class FromKindBits: public BitField<ElementsKind, 8, 8> {};
1379 : class ToKindBits: public BitField<ElementsKind, 0, 8> {};
1380 :
1381 548 : DEFINE_CALL_INTERFACE_DESCRIPTOR(TransitionElementsKind);
1382 730 : DEFINE_HYDROGEN_CODE_STUB(TransitionElementsKind, HydrogenCodeStub);
1383 : };
1384 :
1385 0 : class AllocateHeapNumberStub : public TurboFanCodeStub {
1386 : public:
1387 : explicit AllocateHeapNumberStub(Isolate* isolate)
1388 12944 : : TurboFanCodeStub(isolate) {}
1389 :
1390 : void InitializeDescriptor(CodeStubDescriptor* descriptor) override;
1391 :
1392 1196 : DEFINE_CALL_INTERFACE_DESCRIPTOR(AllocateHeapNumber);
1393 15336 : DEFINE_TURBOFAN_CODE_STUB(AllocateHeapNumber, TurboFanCodeStub);
1394 : };
1395 :
1396 1460 : class CommonArrayConstructorStub : public TurboFanCodeStub {
1397 : protected:
1398 : CommonArrayConstructorStub(Isolate* isolate, ElementsKind kind,
1399 : AllocationSiteOverrideMode override_mode)
1400 2388 : : TurboFanCodeStub(isolate) {
1401 : // It only makes sense to override local allocation site behavior
1402 : // if there is a difference between the global allocation site policy
1403 : // for an ElementsKind and the desired usage of the stub.
1404 : DCHECK(override_mode != DISABLE_ALLOCATION_SITES ||
1405 : AllocationSite::GetMode(kind) == TRACK_ALLOCATION_SITE);
1406 : set_sub_minor_key(ElementsKindBits::encode(kind) |
1407 840 : AllocationSiteOverrideModeBits::encode(override_mode));
1408 : }
1409 :
1410 2388 : void set_sub_minor_key(uint32_t key) { minor_key_ = key; }
1411 :
1412 : uint32_t sub_minor_key() const { return minor_key_; }
1413 :
1414 : CommonArrayConstructorStub(uint32_t key, Isolate* isolate)
1415 0 : : TurboFanCodeStub(key, isolate) {}
1416 :
1417 : public:
1418 860 : ElementsKind elements_kind() const {
1419 : return ElementsKindBits::decode(sub_minor_key());
1420 : }
1421 :
1422 516 : AllocationSiteOverrideMode override_mode() const {
1423 : return AllocationSiteOverrideModeBits::decode(sub_minor_key());
1424 : }
1425 :
1426 : static void GenerateStubsAheadOfTime(Isolate* isolate);
1427 :
1428 : private:
1429 : // Ensure data fits within available bits.
1430 : STATIC_ASSERT(LAST_ALLOCATION_SITE_OVERRIDE_MODE == 1);
1431 :
1432 : class ElementsKindBits : public BitField<ElementsKind, 0, 8> {};
1433 : class AllocationSiteOverrideModeBits
1434 : : public BitField<AllocationSiteOverrideMode, 8, 1> {}; // NOLINT
1435 : };
1436 :
1437 602 : class ArrayNoArgumentConstructorStub : public CommonArrayConstructorStub {
1438 : public:
1439 : ArrayNoArgumentConstructorStub(
1440 : Isolate* isolate, ElementsKind kind,
1441 : AllocationSiteOverrideMode override_mode = DONT_OVERRIDE)
1442 645 : : CommonArrayConstructorStub(isolate, kind, override_mode) {}
1443 :
1444 : private:
1445 344 : void PrintName(std::ostream& os) const override { // NOLINT
1446 344 : os << "ArrayNoArgumentConstructorStub";
1447 344 : }
1448 :
1449 688 : DEFINE_CALL_INTERFACE_DESCRIPTOR(ArrayNoArgumentConstructor);
1450 1677 : DEFINE_TURBOFAN_CODE_STUB(ArrayNoArgumentConstructor,
1451 : CommonArrayConstructorStub);
1452 : };
1453 :
1454 86 : class InternalArrayNoArgumentConstructorStub
1455 : : public CommonArrayConstructorStub {
1456 : public:
1457 : InternalArrayNoArgumentConstructorStub(Isolate* isolate, ElementsKind kind)
1458 172 : : CommonArrayConstructorStub(isolate, kind, DONT_OVERRIDE) {}
1459 :
1460 : private:
1461 86 : void PrintName(std::ostream& os) const override { // NOLINT
1462 86 : os << "InternalArrayNoArgumentConstructorStub";
1463 86 : }
1464 :
1465 172 : DEFINE_CALL_INTERFACE_DESCRIPTOR(ArrayNoArgumentConstructor);
1466 430 : DEFINE_TURBOFAN_CODE_STUB(InternalArrayNoArgumentConstructor,
1467 : CommonArrayConstructorStub);
1468 : };
1469 :
1470 643 : class ArraySingleArgumentConstructorStub : public CommonArrayConstructorStub {
1471 : public:
1472 : ArraySingleArgumentConstructorStub(
1473 : Isolate* isolate, ElementsKind kind,
1474 : AllocationSiteOverrideMode override_mode = DONT_OVERRIDE)
1475 1356 : : CommonArrayConstructorStub(isolate, kind, override_mode) {}
1476 :
1477 : private:
1478 344 : void PrintName(std::ostream& os) const override { // NOLINT
1479 344 : os << "ArraySingleArgumentConstructorStub";
1480 344 : }
1481 :
1482 1330 : DEFINE_CALL_INTERFACE_DESCRIPTOR(ArraySingleArgumentConstructor);
1483 2388 : DEFINE_TURBOFAN_CODE_STUB(ArraySingleArgumentConstructor,
1484 : CommonArrayConstructorStub);
1485 : };
1486 :
1487 129 : class InternalArraySingleArgumentConstructorStub
1488 : : public CommonArrayConstructorStub {
1489 : public:
1490 : InternalArraySingleArgumentConstructorStub(Isolate* isolate,
1491 : ElementsKind kind)
1492 215 : : CommonArrayConstructorStub(isolate, kind, DONT_OVERRIDE) {}
1493 :
1494 : private:
1495 86 : void PrintName(std::ostream& os) const override { // NOLINT
1496 86 : os << "InternalArraySingleArgumentConstructorStub";
1497 86 : }
1498 :
1499 172 : DEFINE_CALL_INTERFACE_DESCRIPTOR(ArraySingleArgumentConstructor);
1500 473 : DEFINE_TURBOFAN_CODE_STUB(InternalArraySingleArgumentConstructor,
1501 : CommonArrayConstructorStub);
1502 : };
1503 :
1504 0 : class ArrayNArgumentsConstructorStub : public PlatformCodeStub {
1505 : public:
1506 : explicit ArrayNArgumentsConstructorStub(Isolate* isolate)
1507 302 : : PlatformCodeStub(isolate) {}
1508 :
1509 0 : CallInterfaceDescriptor GetCallInterfaceDescriptor() const override {
1510 42 : return ArrayNArgumentsConstructorDescriptor(isolate());
1511 : }
1512 :
1513 : private:
1514 431 : DEFINE_PLATFORM_CODE_STUB(ArrayNArgumentsConstructor, PlatformCodeStub);
1515 : };
1516 :
1517 2707 : class StoreSlowElementStub : public TurboFanCodeStub {
1518 : public:
1519 : StoreSlowElementStub(Isolate* isolate, KeyedAccessStoreMode mode)
1520 2707 : : TurboFanCodeStub(isolate) {
1521 2707 : minor_key_ = CommonStoreModeBits::encode(mode);
1522 : }
1523 :
1524 643 : Code::Kind GetCodeKind() const override { return Code::HANDLER; }
1525 643 : ExtraICState GetExtraICState() const override { return Code::KEYED_STORE_IC; }
1526 :
1527 : private:
1528 1286 : DEFINE_CALL_INTERFACE_DESCRIPTOR(StoreWithVector);
1529 5279 : DEFINE_TURBOFAN_CODE_STUB(StoreSlowElement, TurboFanCodeStub);
1530 : };
1531 :
1532 0 : class ToBooleanICStub : public HydrogenCodeStub {
1533 : public:
1534 : ToBooleanICStub(Isolate* isolate, ExtraICState state)
1535 130693 : : HydrogenCodeStub(isolate) {
1536 522772 : set_sub_minor_key(HintsBits::encode(static_cast<uint16_t>(state)));
1537 : }
1538 :
1539 : bool UpdateStatus(Handle<Object> object);
1540 : ToBooleanHints hints() const {
1541 317826 : return ToBooleanHints(HintsBits::decode(sub_minor_key()));
1542 : }
1543 :
1544 21342 : Code::Kind GetCodeKind() const override { return Code::TO_BOOLEAN_IC; }
1545 : void PrintState(std::ostream& os) const override; // NOLINT
1546 :
1547 0 : bool SometimesSetsUpAFrame() override { return false; }
1548 :
1549 231709 : static Handle<Code> GetUninitialized(Isolate* isolate) {
1550 231709 : return ToBooleanICStub(isolate, UNINITIALIZED).GetCode();
1551 : }
1552 :
1553 42684 : ExtraICState GetExtraICState() const override { return hints(); }
1554 :
1555 : InlineCacheState GetICState() const {
1556 392079 : if (hints() == ToBooleanHint::kNone) {
1557 : return ::v8::internal::UNINITIALIZED;
1558 : } else {
1559 : return MONOMORPHIC;
1560 : }
1561 : }
1562 :
1563 : private:
1564 : ToBooleanICStub(Isolate* isolate, InitializationState init_state)
1565 231709 : : HydrogenCodeStub(isolate, init_state) {}
1566 :
1567 : static const int kNumHints = 8;
1568 : STATIC_ASSERT(static_cast<int>(ToBooleanHint::kAny) ==
1569 : ((1 << kNumHints) - 1));
1570 : class HintsBits : public BitField<uint16_t, 0, kNumHints> {};
1571 :
1572 133332 : DEFINE_CALL_INTERFACE_DESCRIPTOR(TypeConversion);
1573 450418 : DEFINE_HYDROGEN_CODE_STUB(ToBooleanIC, HydrogenCodeStub);
1574 : };
1575 :
1576 8238 : class ElementsTransitionAndStoreStub : public TurboFanCodeStub {
1577 : public:
1578 : ElementsTransitionAndStoreStub(Isolate* isolate, ElementsKind from_kind,
1579 : ElementsKind to_kind, bool is_jsarray,
1580 : KeyedAccessStoreMode store_mode)
1581 8238 : : TurboFanCodeStub(isolate) {
1582 8238 : minor_key_ = CommonStoreModeBits::encode(store_mode) |
1583 16476 : FromBits::encode(from_kind) | ToBits::encode(to_kind) |
1584 8238 : IsJSArrayBits::encode(is_jsarray);
1585 : }
1586 :
1587 : ElementsKind from_kind() const { return FromBits::decode(minor_key_); }
1588 : ElementsKind to_kind() const { return ToBits::decode(minor_key_); }
1589 : bool is_jsarray() const { return IsJSArrayBits::decode(minor_key_); }
1590 : KeyedAccessStoreMode store_mode() const {
1591 : return CommonStoreModeBits::decode(minor_key_);
1592 : }
1593 :
1594 2138 : Code::Kind GetCodeKind() const override { return Code::HANDLER; }
1595 2138 : ExtraICState GetExtraICState() const override { return Code::KEYED_STORE_IC; }
1596 :
1597 : private:
1598 : class FromBits
1599 : : public BitField<ElementsKind, CommonStoreModeBits::kNext, 8> {};
1600 : class ToBits : public BitField<ElementsKind, 11, 8> {};
1601 : class IsJSArrayBits : public BitField<bool, 19, 1> {};
1602 :
1603 4276 : DEFINE_CALL_INTERFACE_DESCRIPTOR(StoreTransition);
1604 16790 : DEFINE_TURBOFAN_CODE_STUB(ElementsTransitionAndStore, TurboFanCodeStub);
1605 : };
1606 :
1607 :
1608 26647 : class StubFailureTrampolineStub : public PlatformCodeStub {
1609 : public:
1610 : StubFailureTrampolineStub(Isolate* isolate, StubFunctionMode function_mode)
1611 148019 : : PlatformCodeStub(isolate) {
1612 87333 : minor_key_ = FunctionModeField::encode(function_mode);
1613 : }
1614 :
1615 : static void GenerateAheadOfTime(Isolate* isolate);
1616 :
1617 : private:
1618 : StubFunctionMode function_mode() const {
1619 : return FunctionModeField::decode(minor_key_);
1620 : }
1621 :
1622 : class FunctionModeField : public BitField<StubFunctionMode, 0, 1> {};
1623 :
1624 0 : DEFINE_NULL_CALL_INTERFACE_DESCRIPTOR();
1625 148105 : DEFINE_PLATFORM_CODE_STUB(StubFailureTrampoline, PlatformCodeStub);
1626 : };
1627 :
1628 :
1629 0 : class ProfileEntryHookStub : public PlatformCodeStub {
1630 : public:
1631 0 : explicit ProfileEntryHookStub(Isolate* isolate) : PlatformCodeStub(isolate) {}
1632 :
1633 : // The profile entry hook function is not allowed to cause a GC.
1634 0 : bool SometimesSetsUpAFrame() override { return false; }
1635 :
1636 : // Generates a call to the entry hook if it's enabled.
1637 : static void MaybeCallEntryHook(MacroAssembler* masm);
1638 :
1639 : private:
1640 : static void EntryHookTrampoline(intptr_t function,
1641 : intptr_t stack_pointer,
1642 : Isolate* isolate);
1643 :
1644 : // ProfileEntryHookStub is called at the start of a function, so it has the
1645 : // same register set.
1646 0 : DEFINE_CALL_INTERFACE_DESCRIPTOR(CallFunction)
1647 0 : DEFINE_PLATFORM_CODE_STUB(ProfileEntryHook, PlatformCodeStub);
1648 : };
1649 :
1650 :
1651 0 : class StoreBufferOverflowStub : public PlatformCodeStub {
1652 : public:
1653 : StoreBufferOverflowStub(Isolate* isolate, SaveFPRegsMode save_fp)
1654 254421 : : PlatformCodeStub(isolate) {
1655 326784 : minor_key_ = SaveDoublesBits::encode(save_fp == kSaveFPRegs);
1656 : }
1657 :
1658 : static void GenerateFixedRegStubsAheadOfTime(Isolate* isolate);
1659 0 : bool SometimesSetsUpAFrame() override { return false; }
1660 :
1661 : private:
1662 : bool save_doubles() const { return SaveDoublesBits::decode(minor_key_); }
1663 :
1664 : class SaveDoublesBits : public BitField<bool, 0, 1> {};
1665 :
1666 0 : DEFINE_NULL_CALL_INTERFACE_DESCRIPTOR();
1667 254679 : DEFINE_PLATFORM_CODE_STUB(StoreBufferOverflow, PlatformCodeStub);
1668 : };
1669 :
1670 0 : class SubStringStub : public TurboFanCodeStub {
1671 : public:
1672 890 : explicit SubStringStub(Isolate* isolate) : TurboFanCodeStub(isolate) {}
1673 :
1674 1070 : DEFINE_CALL_INTERFACE_DESCRIPTOR(SubString);
1675 1062 : DEFINE_TURBOFAN_CODE_STUB(SubString, TurboFanCodeStub);
1676 : };
1677 :
1678 :
1679 : #undef DEFINE_CALL_INTERFACE_DESCRIPTOR
1680 : #undef DEFINE_PLATFORM_CODE_STUB
1681 : #undef DEFINE_HANDLER_CODE_STUB
1682 : #undef DEFINE_HYDROGEN_CODE_STUB
1683 : #undef DEFINE_CODE_STUB
1684 : #undef DEFINE_CODE_STUB_BASE
1685 :
1686 : } // namespace internal
1687 : } // namespace v8
1688 :
1689 : #endif // V8_CODE_STUBS_H_
|