28
28
#ifndef V8_CODE_STUBS_H_
29
29
#define V8_CODE_STUBS_H_
31
#include "allocation.h"
31
32
#include "globals.h"
34
35
namespace internal {
36
// List of code stubs used on all platforms. The order in this list is important
37
// as only the stubs up to and including Instanceof allows nested stub calls.
37
// List of code stubs used on all platforms.
38
38
#define CODE_STUB_LIST_ALL_PLATFORMS(V) \
41
V(TypeRecordingBinaryOp) \
50
48
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 */ \
52
57
V(ConvertToDouble) \
53
58
V(WriteInt32ToHeapNumber) \
56
60
V(FastNewClosure) \
57
61
V(FastNewContext) \
58
62
V(FastCloneShallowArray) \
60
63
V(RevertToNumber) \
81
87
#define CODE_STUB_LIST_ARM(V)
90
// List of code stubs only used on MIPS platforms.
91
#ifdef V8_TARGET_ARCH_MIPS
92
#define CODE_STUB_LIST_MIPS(V) \
96
#define CODE_STUB_LIST_MIPS(V)
84
99
// Combined list of code stubs.
85
100
#define CODE_STUB_LIST(V) \
86
101
CODE_STUB_LIST_ALL_PLATFORMS(V) \
102
CODE_STUB_LIST_ARM(V) \
103
CODE_STUB_LIST_MIPS(V)
89
105
// Mode to overwrite BinaryExpression values.
90
106
enum OverwriteMode { NO_OVERWRITE, OVERWRITE_LEFT, OVERWRITE_RIGHT };
152
168
virtual Major MajorKey() = 0;
153
169
virtual int MinorKey() = 0;
155
// The CallFunctionStub needs to override this so it can encode whether a
156
// lazily generated function should be fully optimized or not.
157
virtual InLoopFlag InLoop() { return NOT_IN_LOOP; }
159
// GenericBinaryOpStub needs to override this.
171
// BinaryOpStub needs to override this.
160
172
virtual int GetCodeKind();
162
// GenericBinaryOpStub needs to override this.
174
// BinaryOpStub needs to override this.
163
175
virtual InlineCacheState GetICState() {
164
176
return UNINITIALIZED;
167
179
// Returns a name for logging/debugging purposes.
168
virtual const char* GetName() { return MajorName(MajorKey(), false); }
180
SmartArrayPointer<const char> GetName();
181
virtual void PrintName(StringStream* stream) {
182
stream->Add("%s", MajorName(MajorKey(), false));
171
virtual void Print() { PrintF("%s\n", GetName()); }
185
// Returns whether the code generated for this stub needs to be allocated as
186
// a fixed (non-moveable) code object.
187
virtual bool NeedsImmovableCode() { return false; }
174
189
// Computes the key based on major and minor.
175
190
uint32_t GetKey() {
269
282
Major MajorKey() { return ToNumber; }
270
283
int MinorKey() { return 0; }
271
const char* GetName() { return "ToNumberStub"; }
275
287
class FastNewClosureStub : public CodeStub {
289
explicit FastNewClosureStub(StrictModeFlag strict_mode)
290
: strict_mode_(strict_mode) { }
277
292
void Generate(MacroAssembler* masm);
280
const char* GetName() { return "FastNewClosureStub"; }
281
295
Major MajorKey() { return FastNewClosure; }
282
int MinorKey() { return 0; }
296
int MinorKey() { return strict_mode_; }
298
StrictModeFlag strict_mode_;
366
380
return (flags_ & kReturnTrueFalseObject) != 0;
369
const char* GetName();
383
virtual void PrintName(StringStream* stream);
376
enum NegativeZeroHandling {
384
NO_UNARY_SMI_CODE_IN_STUB = 1 << 0
388
class GenericUnaryOpStub : public CodeStub {
390
GenericUnaryOpStub(Token::Value op,
391
UnaryOverwriteMode overwrite,
393
NegativeZeroHandling negative_zero = kStrictNegativeZero)
395
overwrite_(overwrite),
396
include_smi_code_((flags & NO_UNARY_SMI_CODE_IN_STUB) == 0),
397
negative_zero_(negative_zero) { }
401
UnaryOverwriteMode overwrite_;
402
bool include_smi_code_;
403
NegativeZeroHandling negative_zero_;
405
class OverwriteField: public BitField<UnaryOverwriteMode, 0, 1> {};
406
class IncludeSmiCodeField: public BitField<bool, 1, 1> {};
407
class NegativeZeroField: public BitField<NegativeZeroHandling, 2, 1> {};
408
class OpField: public BitField<Token::Value, 3, kMinorBits - 3> {};
410
Major MajorKey() { return GenericUnaryOp; }
412
return OpField::encode(op_) |
413
OverwriteField::encode(overwrite_) |
414
IncludeSmiCodeField::encode(include_smi_code_) |
415
NegativeZeroField::encode(negative_zero_);
418
void Generate(MacroAssembler* masm);
420
const char* GetName();
575
526
// Unfortunately you have to run without snapshots to see most of these
576
527
// names in the profile since most compare stubs end up in the snapshot.
578
const char* GetName();
581
PrintF("CompareStub (minor %d) (cc %d), (strict %s), "
582
"(never_nan_nan %s), (smi_compare %s) (number_compare %s) ",
584
static_cast<int>(cc_),
585
strict_ ? "true" : "false",
586
never_nan_nan_ ? "true" : "false",
587
include_smi_compare_ ? "inluded" : "not included",
588
include_number_compare_ ? "included" : "not included");
590
if (!lhs_.is(no_reg) && !rhs_.is(no_reg)) {
591
PrintF("(lhs r%d), (rhs r%d)\n", lhs_.code(), rhs_.code());
528
virtual void PrintName(StringStream* stream);
675
609
void Generate(MacroAssembler* masm);
676
610
void GenerateReadElement(MacroAssembler* masm);
677
void GenerateNewObject(MacroAssembler* masm);
679
const char* GetName() { return "ArgumentsAccessStub"; }
683
PrintF("ArgumentsAccessStub (type %d)\n", type_);
611
void GenerateNewStrict(MacroAssembler* masm);
612
void GenerateNewNonStrictFast(MacroAssembler* masm);
613
void GenerateNewNonStrictSlow(MacroAssembler* masm);
615
virtual void PrintName(StringStream* stream);
715
637
int MinorKey() { return 0; }
717
639
void Generate(MacroAssembler* masm);
719
const char* GetName() { return "RegExpConstructResultStub"; }
723
PrintF("RegExpConstructResultStub\n");
729
643
class CallFunctionStub: public CodeStub {
731
CallFunctionStub(int argc, InLoopFlag in_loop, CallFunctionFlags flags)
732
: argc_(argc), in_loop_(in_loop), flags_(flags) { }
645
CallFunctionStub(int argc, CallFunctionFlags flags)
646
: argc_(argc), flags_(flags) { }
734
648
void Generate(MacroAssembler* masm);
743
656
CallFunctionFlags flags_;
747
PrintF("CallFunctionStub (args %d, in_loop %d, flags %d)\n",
749
static_cast<int>(in_loop_),
750
static_cast<int>(flags_));
658
virtual void PrintName(StringStream* stream);
754
660
// Minor key encoding in 32 bits with Bitfield <Type, shift, size>.
755
class InLoopBits: public BitField<InLoopFlag, 0, 1> {};
756
class FlagBits: public BitField<CallFunctionFlags, 1, 1> {};
757
class ArgcBits: public BitField<int, 2, 32 - 2> {};
661
class FlagBits: public BitField<CallFunctionFlags, 0, 1> {};
662
class ArgcBits: public BitField<unsigned, 1, 32 - 1> {};
759
664
Major MajorKey() { return CallFunction; }
761
666
// Encode the parameters in a unique 32 bit value.
762
return InLoopBits::encode(in_loop_)
763
| FlagBits::encode(flags_)
764
| ArgcBits::encode(argc_);
667
return FlagBits::encode(flags_) | ArgcBits::encode(argc_);
767
InLoopFlag InLoop() { return in_loop_; }
768
bool ReceiverMightBeValue() {
769
return (flags_ & RECEIVER_MIGHT_BE_VALUE) != 0;
670
bool ReceiverMightBeImplicit() {
671
return (flags_ & RECEIVER_MIGHT_BE_IMPLICIT) != 0;
945
847
DISALLOW_COPY_AND_ASSIGN(AllowStubCallsScope);
851
class KeyedLoadElementStub : public CodeStub {
853
explicit KeyedLoadElementStub(ElementsKind elements_kind)
854
: elements_kind_(elements_kind)
857
Major MajorKey() { return KeyedLoadElement; }
858
int MinorKey() { return elements_kind_; }
860
void Generate(MacroAssembler* masm);
863
ElementsKind elements_kind_;
865
DISALLOW_COPY_AND_ASSIGN(KeyedLoadElementStub);
869
class KeyedStoreElementStub : public CodeStub {
871
KeyedStoreElementStub(bool is_js_array,
872
ElementsKind elements_kind)
873
: is_js_array_(is_js_array),
874
elements_kind_(elements_kind) { }
876
Major MajorKey() { return KeyedStoreElement; }
878
return (is_js_array_ ? 0 : kElementsKindCount) + elements_kind_;
881
void Generate(MacroAssembler* masm);
885
ElementsKind elements_kind_;
887
DISALLOW_COPY_AND_ASSIGN(KeyedStoreElementStub);
891
class ToBooleanStub: public CodeStub {
904
// At most 8 different types can be distinguished, because the Code object
905
// only has room for a single byte to hold a set of these types. :-P
906
STATIC_ASSERT(NUMBER_OF_TYPES <= 8);
911
explicit Types(byte bits) : set_(bits) {}
913
bool IsEmpty() const { return set_.IsEmpty(); }
914
bool Contains(Type type) const { return set_.Contains(type); }
915
void Add(Type type) { set_.Add(type); }
916
byte ToByte() const { return set_.ToIntegral(); }
917
void Print(StringStream* stream) const;
918
void TraceTransition(Types to) const;
919
bool Record(Handle<Object> object);
920
bool NeedsMap() const;
921
bool CanBeUndetectable() const;
924
EnumSet<Type, byte> set_;
927
static Types no_types() { return Types(); }
928
static Types all_types() { return Types((1 << NUMBER_OF_TYPES) - 1); }
930
explicit ToBooleanStub(Register tos, Types types = Types())
931
: tos_(tos), types_(types) { }
933
void Generate(MacroAssembler* masm);
934
virtual int GetCodeKind() { return Code::TO_BOOLEAN_IC; }
935
virtual void PrintName(StringStream* stream);
938
Major MajorKey() { return ToBoolean; }
939
int MinorKey() { return (tos_.code() << NUMBER_OF_TYPES) | types_.ToByte(); }
941
virtual void FinishCode(Code* code) {
942
code->set_to_boolean_state(types_.ToByte());
945
void CheckOddball(MacroAssembler* masm,
947
Heap::RootListIndex value,
949
void GenerateTypeTransition(MacroAssembler* masm);
948
955
} } // namespace v8::internal
950
957
#endif // V8_CODE_STUBS_H_