50
V(StoreBufferOverflow) \
48
52
V(TranscendentalCache) \
50
/* All stubs above this line only exist in a few versions, which are */ \
51
/* generated ahead of time. Therefore compiling a call to one of */ \
52
/* them can't cause a new stub to be compiled, so compiling a call to */ \
53
/* them is GC safe. The ones below this line exist in many variants */ \
54
/* so code compiling a call to one can cause a GC. This means they */ \
55
/* can't be called from other stubs, since stub generation code is */ \
57
54
V(ConvertToDouble) \
58
55
V(WriteInt32ToHeapNumber) \
60
57
V(FastNewClosure) \
61
58
V(FastNewContext) \
59
V(FastNewBlockContext) \
62
60
V(FastCloneShallowArray) \
61
V(FastCloneShallowObject) \
67
64
V(ArgumentsAccess) \
69
65
V(RegExpConstructResult) \
70
66
V(NumberToString) \
73
69
V(KeyedLoadElement) \
74
70
V(KeyedStoreElement) \
75
71
V(DebuggerStatement) \
76
V(StringDictionaryNegativeLookup)
72
V(StringDictionaryLookup) \
73
V(ElementsTransitionAndStore) \
74
V(StoreArrayLiteralElement)
78
76
// List of code stubs only used on ARM platforms.
79
77
#ifdef V8_TARGET_ARCH_ARM
121
119
// Retrieve the code for the stub. Generate the code if needed.
122
120
Handle<Code> GetCode();
124
// Retrieve the code for the stub if already generated. Do not
125
// generate the code if not already generated and instead return a
126
// retry after GC Failure object.
127
MUST_USE_RESULT MaybeObject* TryGetCode();
129
122
static Major MajorKeyFromKey(uint32_t key) {
130
123
return static_cast<Major>(MajorKeyBits::decode(key));
143
136
virtual ~CodeStub() {}
138
bool CompilingCallsToThisStubIsGCSafe() {
139
bool is_pregenerated = IsPregenerated();
141
CHECK(!is_pregenerated || FindCodeInCache(&code));
142
return is_pregenerated;
145
// See comment above, where Instanceof is defined.
146
virtual bool IsPregenerated() { return false; }
148
static void GenerateStubsAheadOfTime();
149
static void GenerateFPStubs();
151
// Some stubs put untagged junk on the stack that cannot be scanned by the
152
// GC. This means that we must be statically sure that no GC can occur while
153
// they are running. If that is the case they should override this to return
154
// true, which will cause an assertion if we try to call something that can
155
// GC or if we try to put a stack frame on top of the junk, which would not
156
// result in a traversable stack.
157
virtual bool SometimesSetsUpAFrame() { return true; }
159
// Lookup the code in the (possibly custom) cache.
160
bool FindCodeInCache(Code** code_out);
146
163
static const int kMajorBits = 6;
147
164
static const int kMinorBits = kBitsPerInt - kSmiTagSize - kMajorBits;
150
// Lookup the code in the (possibly custom) cache.
151
bool FindCodeInCache(Code** code_out);
153
167
// Nonvirtual wrapper around the stub-specific Generate function. Call
154
168
// this function to set up the macro assembler and generate the code.
155
169
void GenerateCode(MacroAssembler* masm);
162
176
void RecordCodeGeneration(Code* code, MacroAssembler* masm);
164
178
// Finish the code object after it has been generated.
165
virtual void FinishCode(Code* code) { }
179
virtual void FinishCode(Handle<Code> code) { }
181
// Activate newly generated stub. Is called after
182
// registering stub in the stub cache.
183
virtual void Activate(Code* code) { }
167
185
// Returns information for computing the number key.
168
186
virtual Major MajorKey() = 0;
179
197
// Returns a name for logging/debugging purposes.
180
198
SmartArrayPointer<const char> GetName();
181
virtual void PrintName(StringStream* stream) {
182
stream->Add("%s", MajorName(MajorKey(), false));
199
virtual void PrintName(StringStream* stream);
185
201
// Returns whether the code generated for this stub needs to be allocated as
186
202
// a fixed (non-moveable) code object.
193
209
MajorKeyBits::encode(MajorKey());
196
// See comment above, where Instanceof is defined.
197
bool AllowsStubCalls() { return MajorKey() <= Instanceof; }
199
212
class MajorKeyBits: public BitField<uint32_t, 0, kMajorBits> {};
200
213
class MinorKeyBits: public BitField<uint32_t, kMajorBits, kMinorBits> {};
287
300
class FastNewClosureStub : public CodeStub {
289
explicit FastNewClosureStub(StrictModeFlag strict_mode)
290
: strict_mode_(strict_mode) { }
302
explicit FastNewClosureStub(LanguageMode language_mode)
303
: language_mode_(language_mode) { }
292
305
void Generate(MacroAssembler* masm);
295
308
Major MajorKey() { return FastNewClosure; }
296
int MinorKey() { return strict_mode_; }
309
int MinorKey() { return language_mode_ == CLASSIC_MODE
310
? kNonStrictMode : kStrictMode; }
298
StrictModeFlag strict_mode_;
312
LanguageMode language_mode_;
304
318
static const int kMaximumSlots = 64;
306
320
explicit FastNewContextStub(int slots) : slots_(slots) {
307
ASSERT(slots_ > 0 && slots <= kMaximumSlots);
321
ASSERT(slots_ > 0 && slots_ <= kMaximumSlots);
310
324
void Generate(MacroAssembler* masm);
334
class FastNewBlockContextStub : public CodeStub {
336
static const int kMaximumSlots = 64;
338
explicit FastNewBlockContextStub(int slots) : slots_(slots) {
339
ASSERT(slots_ > 0 && slots_ <= kMaximumSlots);
342
void Generate(MacroAssembler* masm);
347
Major MajorKey() { return FastNewBlockContext; }
348
int MinorKey() { return slots_; }
320
352
class FastCloneShallowArrayStub : public CodeStub {
322
354
// Maximum length of copied elements array.
327
COPY_ON_WRITE_ELEMENTS
359
CLONE_DOUBLE_ELEMENTS,
360
COPY_ON_WRITE_ELEMENTS,
330
364
FastCloneShallowArrayStub(Mode mode, int length)
332
366
length_((mode == COPY_ON_WRITE_ELEMENTS) ? 0 : length) {
333
ASSERT(length_ >= 0);
334
ASSERT(length_ <= kMaximumClonedLength);
367
ASSERT_GE(length_, 0);
368
ASSERT_LE(length_, kMaximumClonedLength);
337
371
void Generate(MacroAssembler* masm);
343
377
Major MajorKey() { return FastCloneShallowArray; }
345
ASSERT(mode_ == 0 || mode_ == 1);
346
return (length_ << 1) | mode_;
379
ASSERT(mode_ == 0 || mode_ == 1 || mode_ == 2 || mode_ == 3);
380
return length_ * 4 + mode_;
385
class FastCloneShallowObjectStub : public CodeStub {
387
// Maximum number of properties in copied object.
388
static const int kMaximumClonedProperties = 6;
390
explicit FastCloneShallowObjectStub(int length) : length_(length) {
391
ASSERT_GE(length_, 0);
392
ASSERT_LE(length_, kMaximumClonedProperties);
395
void Generate(MacroAssembler* masm);
400
Major MajorKey() { return FastCloneShallowObject; }
401
int MinorKey() { return length_; }
410
464
class OpField: public BitField<int, 0, 3> { };
411
465
class StateField: public BitField<int, 3, 5> { };
413
virtual void FinishCode(Code* code) { code->set_compare_state(state_); }
467
virtual void FinishCode(Handle<Code> code) {
468
code->set_compare_state(state_);
415
471
virtual CodeStub::Major MajorKey() { return CompareIC; }
416
472
virtual int MinorKey();
532
588
class CEntryStub : public CodeStub {
534
explicit CEntryStub(int result_size)
535
: result_size_(result_size), save_doubles_(false) { }
590
explicit CEntryStub(int result_size,
591
SaveFPRegsMode save_doubles = kDontSaveFPRegs)
592
: result_size_(result_size), save_doubles_(save_doubles) { }
537
594
void Generate(MacroAssembler* masm);
538
void SaveDoubles() { save_doubles_ = true; }
596
// The version of this stub that doesn't save doubles is generated ahead of
597
// time, so it's OK to call it from other stubs that can't cope with GC during
598
// their code generation. On machines that always have gp registers (x64) we
599
// can generate both variants ahead of time.
600
virtual bool IsPregenerated();
601
static void GenerateAheadOfTime();
541
604
void GenerateCore(MacroAssembler* masm,
648
715
void Generate(MacroAssembler* masm);
717
virtual void FinishCode(Handle<Code> code);
719
static void Clear(Heap* heap, Address address);
721
static Object* GetCachedValue(Address address);
650
723
static int ExtractArgcFromMinorKey(int minor_key) {
651
724
return ArgcBits::decode(minor_key);
727
// The object that indicates an uninitialized cache.
728
static Handle<Object> UninitializedSentinel(Isolate* isolate) {
729
return isolate->factory()->the_hole_value();
732
// A raw version of the uninitialized sentinel that's safe to read during
733
// garbage collection (e.g., for patching the cache).
734
static Object* RawUninitializedSentinel(Heap* heap) {
735
return heap->raw_unchecked_the_hole_value();
738
// The object that indicates a megamorphic state.
739
static Handle<Object> MegamorphicSentinel(Isolate* isolate) {
740
return isolate->factory()->undefined_value();
656
745
CallFunctionFlags flags_;
658
747
virtual void PrintName(StringStream* stream);
660
749
// Minor key encoding in 32 bits with Bitfield <Type, shift, size>.
661
class FlagBits: public BitField<CallFunctionFlags, 0, 1> {};
662
class ArgcBits: public BitField<unsigned, 1, 32 - 1> {};
750
class FlagBits: public BitField<CallFunctionFlags, 0, 2> {};
751
class ArgcBits: public BitField<unsigned, 2, 32 - 2> {};
664
753
Major MajorKey() { return CallFunction; }
706
798
StringIndexFlags index_flags)
707
799
: object_(object),
711
802
receiver_not_string_(receiver_not_string),
712
803
index_not_number_(index_not_number),
713
804
index_out_of_range_(index_out_of_range),
714
805
index_flags_(index_flags) {
715
ASSERT(!scratch_.is(object_));
716
ASSERT(!scratch_.is(index_));
717
ASSERT(!scratch_.is(result_));
718
806
ASSERT(!result_.is(object_));
719
807
ASSERT(!result_.is(index_));
804
890
StringIndexFlags index_flags)
805
891
: char_code_at_generator_(object,
809
894
receiver_not_string,
810
895
index_not_number,
811
896
index_out_of_range,
813
char_from_code_generator_(scratch2, result) {}
898
char_from_code_generator_(scratch, result) {}
815
900
// Generates the fast case code. On the fallthrough path |result|
816
901
// register contains the result.
934
1019
virtual int GetCodeKind() { return Code::TO_BOOLEAN_IC; }
935
1020
virtual void PrintName(StringStream* stream);
1022
virtual bool SometimesSetsUpAFrame() { return false; }
938
1025
Major MajorKey() { return ToBoolean; }
939
1026
int MinorKey() { return (tos_.code() << NUMBER_OF_TYPES) | types_.ToByte(); }
941
virtual void FinishCode(Code* code) {
1028
virtual void FinishCode(Handle<Code> code) {
942
1029
code->set_to_boolean_state(types_.ToByte());
1043
class ElementsTransitionAndStoreStub : public CodeStub {
1045
ElementsTransitionAndStoreStub(ElementsKind from,
1048
StrictModeFlag strict_mode)
1051
is_jsarray_(is_jsarray),
1052
strict_mode_(strict_mode) {}
1055
class FromBits: public BitField<ElementsKind, 0, 8> {};
1056
class ToBits: public BitField<ElementsKind, 8, 8> {};
1057
class IsJSArrayBits: public BitField<bool, 16, 8> {};
1058
class StrictModeBits: public BitField<StrictModeFlag, 24, 8> {};
1060
Major MajorKey() { return ElementsTransitionAndStore; }
1062
return FromBits::encode(from_) |
1063
ToBits::encode(to_) |
1064
IsJSArrayBits::encode(is_jsarray_) |
1065
StrictModeBits::encode(strict_mode_);
1068
void Generate(MacroAssembler* masm);
1073
StrictModeFlag strict_mode_;
1075
DISALLOW_COPY_AND_ASSIGN(ElementsTransitionAndStoreStub);
1079
class StoreArrayLiteralElementStub : public CodeStub {
1081
explicit StoreArrayLiteralElementStub() {}
1084
Major MajorKey() { return StoreArrayLiteralElement; }
1085
int MinorKey() { return 0; }
1087
void Generate(MacroAssembler* masm);
1089
DISALLOW_COPY_AND_ASSIGN(StoreArrayLiteralElementStub);
955
1092
} } // namespace v8::internal
957
1094
#endif // V8_CODE_STUBS_H_