Make more use of the NumberInfo data.
Makes NumberInfo into a real class. Fix bug where NumberInfo was lost in ToRegister. Allow 17 bits in safe Smis instead of 16. Review URL: http://codereview.chromium.org/668151 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@4046 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
parent
77d63cc29e
commit
00a44ae51a
@ -295,7 +295,7 @@ void VirtualFrame::EmitPop(Register reg) {
|
||||
|
||||
void VirtualFrame::EmitPush(Register reg) {
|
||||
ASSERT(stack_pointer_ == element_count() - 1);
|
||||
elements_.Add(FrameElement::MemoryElement(NumberInfo::kUnknown));
|
||||
elements_.Add(FrameElement::MemoryElement(NumberInfo::Unknown()));
|
||||
stack_pointer_++;
|
||||
__ push(reg);
|
||||
}
|
||||
|
@ -69,7 +69,7 @@ class VirtualFrame : public ZoneObject {
|
||||
|
||||
// Create a duplicate of an existing valid frame element.
|
||||
FrameElement CopyElementAt(int index,
|
||||
NumberInfo::Type info = NumberInfo::kUnknown);
|
||||
NumberInfo info = NumberInfo::Unknown());
|
||||
|
||||
// The number of elements on the virtual frame.
|
||||
int element_count() { return elements_.length(); }
|
||||
@ -344,7 +344,7 @@ class VirtualFrame : public ZoneObject {
|
||||
void EmitPushMultiple(int count, int src_regs);
|
||||
|
||||
// Push an element on the virtual frame.
|
||||
inline void Push(Register reg, NumberInfo::Type info = NumberInfo::kUnknown);
|
||||
inline void Push(Register reg, NumberInfo info = NumberInfo::Unknown());
|
||||
inline void Push(Handle<Object> value);
|
||||
inline void Push(Smi* value);
|
||||
|
||||
|
@ -53,23 +53,25 @@ class FrameElement BASE_EMBEDDED {
|
||||
SYNCED
|
||||
};
|
||||
|
||||
inline NumberInfo::Type number_info() {
|
||||
inline NumberInfo number_info() {
|
||||
// Copied elements do not have number info. Instead
|
||||
// we have to inspect their backing element in the frame.
|
||||
ASSERT(!is_copy());
|
||||
if (!is_constant()) return NumberInfoField::decode(value_);
|
||||
if (!is_constant()) {
|
||||
return NumberInfo::FromInt(NumberInfoField::decode(value_));
|
||||
}
|
||||
Handle<Object> value = handle();
|
||||
if (value->IsSmi()) return NumberInfo::kSmi;
|
||||
if (value->IsHeapNumber()) return NumberInfo::kHeapNumber;
|
||||
return NumberInfo::kUnknown;
|
||||
if (value->IsSmi()) return NumberInfo::Smi();
|
||||
if (value->IsHeapNumber()) return NumberInfo::HeapNumber();
|
||||
return NumberInfo::Unknown();
|
||||
}
|
||||
|
||||
inline void set_number_info(NumberInfo::Type info) {
|
||||
inline void set_number_info(NumberInfo info) {
|
||||
// Copied elements do not have number info. Instead
|
||||
// we have to inspect their backing element in the frame.
|
||||
ASSERT(!is_copy());
|
||||
value_ = value_ & ~NumberInfoField::mask();
|
||||
value_ = value_ | NumberInfoField::encode(info);
|
||||
value_ = value_ | NumberInfoField::encode(info.ToInt());
|
||||
}
|
||||
|
||||
// The default constructor creates an invalid frame element.
|
||||
@ -77,7 +79,7 @@ class FrameElement BASE_EMBEDDED {
|
||||
value_ = TypeField::encode(INVALID)
|
||||
| CopiedField::encode(false)
|
||||
| SyncedField::encode(false)
|
||||
| NumberInfoField::encode(NumberInfo::kUninitialized)
|
||||
| NumberInfoField::encode(NumberInfo::Uninitialized().ToInt())
|
||||
| DataField::encode(0);
|
||||
}
|
||||
|
||||
@ -88,7 +90,7 @@ class FrameElement BASE_EMBEDDED {
|
||||
}
|
||||
|
||||
// Factory function to construct an in-memory frame element.
|
||||
static FrameElement MemoryElement(NumberInfo::Type info) {
|
||||
static FrameElement MemoryElement(NumberInfo info) {
|
||||
FrameElement result(MEMORY, no_reg, SYNCED, info);
|
||||
return result;
|
||||
}
|
||||
@ -96,7 +98,7 @@ class FrameElement BASE_EMBEDDED {
|
||||
// Factory function to construct an in-register frame element.
|
||||
static FrameElement RegisterElement(Register reg,
|
||||
SyncFlag is_synced,
|
||||
NumberInfo::Type info) {
|
||||
NumberInfo info) {
|
||||
return FrameElement(REGISTER, reg, is_synced, info);
|
||||
}
|
||||
|
||||
@ -210,11 +212,11 @@ class FrameElement BASE_EMBEDDED {
|
||||
FrameElement(Type type,
|
||||
Register reg,
|
||||
SyncFlag is_synced,
|
||||
NumberInfo::Type info) {
|
||||
NumberInfo info) {
|
||||
value_ = TypeField::encode(type)
|
||||
| CopiedField::encode(false)
|
||||
| SyncedField::encode(is_synced != NOT_SYNCED)
|
||||
| NumberInfoField::encode(info)
|
||||
| NumberInfoField::encode(info.ToInt())
|
||||
| DataField::encode(reg.code_ > 0 ? reg.code_ : 0);
|
||||
}
|
||||
|
||||
@ -223,7 +225,7 @@ class FrameElement BASE_EMBEDDED {
|
||||
value_ = TypeField::encode(CONSTANT)
|
||||
| CopiedField::encode(false)
|
||||
| SyncedField::encode(is_synced != NOT_SYNCED)
|
||||
| NumberInfoField::encode(NumberInfo::kUninitialized)
|
||||
| NumberInfoField::encode(NumberInfo::Uninitialized().ToInt())
|
||||
| DataField::encode(ConstantList()->length());
|
||||
ConstantList()->Add(value);
|
||||
}
|
||||
@ -252,8 +254,8 @@ class FrameElement BASE_EMBEDDED {
|
||||
class TypeField: public BitField<Type, 0, 3> {};
|
||||
class CopiedField: public BitField<bool, 3, 1> {};
|
||||
class SyncedField: public BitField<bool, 4, 1> {};
|
||||
class NumberInfoField: public BitField<NumberInfo::Type, 5, 3> {};
|
||||
class DataField: public BitField<uint32_t, 8, 32 - 8> {};
|
||||
class NumberInfoField: public BitField<int, 5, 4> {};
|
||||
class DataField: public BitField<uint32_t, 9, 32 - 9> {};
|
||||
|
||||
friend class VirtualFrame;
|
||||
};
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -496,8 +496,8 @@ class CodeGenerator: public AstVisitor {
|
||||
|
||||
// To prevent long attacker-controlled byte sequences, integer constants
|
||||
// from the JavaScript source are loaded in two parts if they are larger
|
||||
// than 16 bits.
|
||||
static const int kMaxSmiInlinedBits = 16;
|
||||
// than 17 bits.
|
||||
static const int kMaxSmiInlinedBits = 17;
|
||||
bool IsUnsafeSmi(Handle<Object> value);
|
||||
// Load an integer constant x into a register target or into the stack using
|
||||
// at most 16 bits of user-controlled data per assembly operation.
|
||||
@ -695,7 +695,7 @@ class GenericBinaryOpStub: public CodeStub {
|
||||
GenericBinaryOpStub(Token::Value op,
|
||||
OverwriteMode mode,
|
||||
GenericBinaryFlags flags,
|
||||
NumberInfo::Type operands_type = NumberInfo::kUnknown)
|
||||
NumberInfo operands_type)
|
||||
: op_(op),
|
||||
mode_(mode),
|
||||
flags_(flags),
|
||||
@ -704,6 +704,9 @@ class GenericBinaryOpStub: public CodeStub {
|
||||
static_operands_type_(operands_type),
|
||||
runtime_operands_type_(BinaryOpIC::DEFAULT),
|
||||
name_(NULL) {
|
||||
if (static_operands_type_.IsSmi()) {
|
||||
mode_ = NO_OVERWRITE;
|
||||
}
|
||||
use_sse3_ = CpuFeatures::IsSupported(SSE3);
|
||||
ASSERT(OpBits::is_valid(Token::NUM_TOKENS));
|
||||
}
|
||||
@ -715,7 +718,8 @@ class GenericBinaryOpStub: public CodeStub {
|
||||
args_in_registers_(ArgsInRegistersBits::decode(key)),
|
||||
args_reversed_(ArgsReversedBits::decode(key)),
|
||||
use_sse3_(SSE3Bits::decode(key)),
|
||||
static_operands_type_(StaticTypeInfoBits::decode(key)),
|
||||
static_operands_type_(NumberInfo::ExpandedRepresentation(
|
||||
StaticTypeInfoBits::decode(key))),
|
||||
runtime_operands_type_(runtime_operands_type),
|
||||
name_(NULL) {
|
||||
}
|
||||
@ -741,7 +745,7 @@ class GenericBinaryOpStub: public CodeStub {
|
||||
bool use_sse3_;
|
||||
|
||||
// Number type information of operands, determined by code generator.
|
||||
NumberInfo::Type static_operands_type_;
|
||||
NumberInfo static_operands_type_;
|
||||
|
||||
// Operand type information determined at runtime.
|
||||
BinaryOpIC::TypeInfo runtime_operands_type_;
|
||||
@ -760,7 +764,7 @@ class GenericBinaryOpStub: public CodeStub {
|
||||
static_cast<int>(flags_),
|
||||
static_cast<int>(args_in_registers_),
|
||||
static_cast<int>(args_reversed_),
|
||||
NumberInfo::ToString(static_operands_type_));
|
||||
static_operands_type_.ToString());
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -771,7 +775,7 @@ class GenericBinaryOpStub: public CodeStub {
|
||||
class ArgsInRegistersBits: public BitField<bool, 10, 1> {};
|
||||
class ArgsReversedBits: public BitField<bool, 11, 1> {};
|
||||
class FlagBits: public BitField<GenericBinaryFlags, 12, 1> {};
|
||||
class StaticTypeInfoBits: public BitField<NumberInfo::Type, 13, 3> {};
|
||||
class StaticTypeInfoBits: public BitField<int, 13, 3> {};
|
||||
class RuntimeTypeInfoBits: public BitField<BinaryOpIC::TypeInfo, 16, 2> {};
|
||||
|
||||
Major MajorKey() { return GenericBinaryOp; }
|
||||
@ -783,7 +787,8 @@ class GenericBinaryOpStub: public CodeStub {
|
||||
| SSE3Bits::encode(use_sse3_)
|
||||
| ArgsInRegistersBits::encode(args_in_registers_)
|
||||
| ArgsReversedBits::encode(args_reversed_)
|
||||
| StaticTypeInfoBits::encode(static_operands_type_)
|
||||
| StaticTypeInfoBits::encode(
|
||||
static_operands_type_.ThreeBitRepresentation())
|
||||
| RuntimeTypeInfoBits::encode(runtime_operands_type_);
|
||||
}
|
||||
|
||||
|
@ -1130,7 +1130,8 @@ void FullCodeGenerator::EmitBinaryOp(Token::Value op,
|
||||
__ push(result_register());
|
||||
GenericBinaryOpStub stub(op,
|
||||
NO_OVERWRITE,
|
||||
NO_GENERIC_BINARY_FLAGS);
|
||||
NO_GENERIC_BINARY_FLAGS,
|
||||
NumberInfo::Unknown());
|
||||
__ CallStub(&stub);
|
||||
Apply(context, eax);
|
||||
}
|
||||
@ -1744,7 +1745,8 @@ void FullCodeGenerator::VisitCountOperation(CountOperation* expr) {
|
||||
// Call stub for +1/-1.
|
||||
GenericBinaryOpStub stub(expr->binary_op(),
|
||||
NO_OVERWRITE,
|
||||
NO_GENERIC_BINARY_FLAGS);
|
||||
NO_GENERIC_BINARY_FLAGS,
|
||||
NumberInfo::Unknown());
|
||||
stub.GenerateCall(masm(), eax, Smi::FromInt(1));
|
||||
__ bind(&done);
|
||||
|
||||
|
@ -49,6 +49,7 @@ void Result::ToRegister() {
|
||||
Immediate(handle()));
|
||||
}
|
||||
// This result becomes a copy of the fresh one.
|
||||
fresh.set_number_info(number_info());
|
||||
*this = fresh;
|
||||
}
|
||||
ASSERT(is_register());
|
||||
|
@ -162,7 +162,7 @@ void VirtualFrame::MakeMergable() {
|
||||
if (element.is_constant() || element.is_copy()) {
|
||||
if (element.is_synced()) {
|
||||
// Just spill.
|
||||
elements_[i] = FrameElement::MemoryElement(NumberInfo::kUnknown);
|
||||
elements_[i] = FrameElement::MemoryElement(NumberInfo::Unknown());
|
||||
} else {
|
||||
// Allocate to a register.
|
||||
FrameElement backing_element; // Invalid if not a copy.
|
||||
@ -174,7 +174,7 @@ void VirtualFrame::MakeMergable() {
|
||||
elements_[i] =
|
||||
FrameElement::RegisterElement(fresh.reg(),
|
||||
FrameElement::NOT_SYNCED,
|
||||
NumberInfo::kUnknown);
|
||||
NumberInfo::Unknown());
|
||||
Use(fresh.reg(), i);
|
||||
|
||||
// Emit a move.
|
||||
@ -207,7 +207,7 @@ void VirtualFrame::MakeMergable() {
|
||||
// The copy flag is not relied on before the end of this loop,
|
||||
// including when registers are spilled.
|
||||
elements_[i].clear_copied();
|
||||
elements_[i].set_number_info(NumberInfo::kUnknown);
|
||||
elements_[i].set_number_info(NumberInfo::Unknown());
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1062,7 +1062,7 @@ Result VirtualFrame::Pop() {
|
||||
ASSERT(element.is_valid());
|
||||
|
||||
// Get number type information of the result.
|
||||
NumberInfo::Type info;
|
||||
NumberInfo info;
|
||||
if (!element.is_copy()) {
|
||||
info = element.number_info();
|
||||
} else {
|
||||
@ -1137,7 +1137,7 @@ void VirtualFrame::EmitPop(Operand operand) {
|
||||
}
|
||||
|
||||
|
||||
void VirtualFrame::EmitPush(Register reg, NumberInfo::Type info) {
|
||||
void VirtualFrame::EmitPush(Register reg, NumberInfo info) {
|
||||
ASSERT(stack_pointer_ == element_count() - 1);
|
||||
elements_.Add(FrameElement::MemoryElement(info));
|
||||
stack_pointer_++;
|
||||
@ -1145,7 +1145,7 @@ void VirtualFrame::EmitPush(Register reg, NumberInfo::Type info) {
|
||||
}
|
||||
|
||||
|
||||
void VirtualFrame::EmitPush(Operand operand, NumberInfo::Type info) {
|
||||
void VirtualFrame::EmitPush(Operand operand, NumberInfo info) {
|
||||
ASSERT(stack_pointer_ == element_count() - 1);
|
||||
elements_.Add(FrameElement::MemoryElement(info));
|
||||
stack_pointer_++;
|
||||
@ -1153,7 +1153,7 @@ void VirtualFrame::EmitPush(Operand operand, NumberInfo::Type info) {
|
||||
}
|
||||
|
||||
|
||||
void VirtualFrame::EmitPush(Immediate immediate, NumberInfo::Type info) {
|
||||
void VirtualFrame::EmitPush(Immediate immediate, NumberInfo info) {
|
||||
ASSERT(stack_pointer_ == element_count() - 1);
|
||||
elements_.Add(FrameElement::MemoryElement(info));
|
||||
stack_pointer_++;
|
||||
|
@ -84,7 +84,7 @@ class VirtualFrame: public ZoneObject {
|
||||
|
||||
// Create a duplicate of an existing valid frame element.
|
||||
FrameElement CopyElementAt(int index,
|
||||
NumberInfo::Type info = NumberInfo::kUninitialized);
|
||||
NumberInfo info = NumberInfo::Uninitialized());
|
||||
|
||||
// The number of elements on the virtual frame.
|
||||
int element_count() { return elements_.length(); }
|
||||
@ -388,14 +388,14 @@ class VirtualFrame: public ZoneObject {
|
||||
// Push an element on top of the expression stack and emit a
|
||||
// corresponding push instruction.
|
||||
void EmitPush(Register reg,
|
||||
NumberInfo::Type info = NumberInfo::kUnknown);
|
||||
NumberInfo info = NumberInfo::Unknown());
|
||||
void EmitPush(Operand operand,
|
||||
NumberInfo::Type info = NumberInfo::kUnknown);
|
||||
NumberInfo info = NumberInfo::Unknown());
|
||||
void EmitPush(Immediate immediate,
|
||||
NumberInfo::Type info = NumberInfo::kUnknown);
|
||||
NumberInfo info = NumberInfo::Unknown());
|
||||
|
||||
// Push an element on the virtual frame.
|
||||
inline void Push(Register reg, NumberInfo::Type info = NumberInfo::kUnknown);
|
||||
inline void Push(Register reg, NumberInfo info = NumberInfo::Unknown());
|
||||
inline void Push(Handle<Object> value);
|
||||
inline void Push(Smi* value);
|
||||
|
||||
|
@ -46,7 +46,7 @@ void JumpTarget::InitializeEntryElement(int index, FrameElement* target) {
|
||||
entry_frame_->elements_[target->index()].set_copied();
|
||||
}
|
||||
if (direction_ == BIDIRECTIONAL && !target->is_copy()) {
|
||||
element->set_number_info(NumberInfo::kUnknown);
|
||||
element->set_number_info(NumberInfo::Unknown());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -135,7 +135,7 @@ void JumpTarget::ComputeEntryFrame() {
|
||||
FrameElement* target = elements[index];
|
||||
if (target == NULL) {
|
||||
entry_frame_->elements_.Add(
|
||||
FrameElement::MemoryElement(NumberInfo::kUninitialized));
|
||||
FrameElement::MemoryElement(NumberInfo::Uninitialized()));
|
||||
} else {
|
||||
entry_frame_->elements_.Add(*target);
|
||||
InitializeEntryElement(index, target);
|
||||
@ -152,12 +152,12 @@ void JumpTarget::ComputeEntryFrame() {
|
||||
RegisterFile candidate_registers;
|
||||
int best_count = kMinInt;
|
||||
int best_reg_num = RegisterAllocator::kInvalidRegister;
|
||||
NumberInfo::Type info = NumberInfo::kUninitialized;
|
||||
NumberInfo info = NumberInfo::Uninitialized();
|
||||
|
||||
for (int j = 0; j < reaching_frames_.length(); j++) {
|
||||
FrameElement element = reaching_frames_[j]->elements_[i];
|
||||
if (direction_ == BIDIRECTIONAL) {
|
||||
info = NumberInfo::kUnknown;
|
||||
info = NumberInfo::Unknown();
|
||||
} else if (!element.is_copy()) {
|
||||
info = NumberInfo::Combine(info, element.number_info());
|
||||
} else {
|
||||
@ -181,7 +181,7 @@ void JumpTarget::ComputeEntryFrame() {
|
||||
|
||||
// We must have a number type information now (not for copied elements).
|
||||
ASSERT(entry_frame_->elements_[i].is_copy()
|
||||
|| info != NumberInfo::kUninitialized);
|
||||
|| !info.IsUninitialized());
|
||||
|
||||
// If the value is synced on all frames, put it in memory. This
|
||||
// costs nothing at the merge code but will incur a
|
||||
@ -211,7 +211,7 @@ void JumpTarget::ComputeEntryFrame() {
|
||||
Register reg = RegisterAllocator::ToRegister(best_reg_num);
|
||||
entry_frame_->elements_[i] =
|
||||
FrameElement::RegisterElement(reg, FrameElement::NOT_SYNCED,
|
||||
NumberInfo::kUninitialized);
|
||||
NumberInfo::Uninitialized());
|
||||
if (is_copied) entry_frame_->elements_[i].set_copied();
|
||||
entry_frame_->set_register_location(reg, i);
|
||||
}
|
||||
@ -225,8 +225,7 @@ void JumpTarget::ComputeEntryFrame() {
|
||||
if (direction_ == BIDIRECTIONAL) {
|
||||
for (int i = 0; i < length; ++i) {
|
||||
if (!entry_frame_->elements_[i].is_copy()) {
|
||||
ASSERT(entry_frame_->elements_[i].number_info() ==
|
||||
NumberInfo::kUnknown);
|
||||
ASSERT(entry_frame_->elements_[i].number_info().IsUnknown());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -31,42 +31,160 @@
|
||||
namespace v8 {
|
||||
namespace internal {
|
||||
|
||||
class NumberInfo : public AllStatic {
|
||||
// Unknown
|
||||
// |
|
||||
// Number
|
||||
// / |
|
||||
// HeapNumber Integer32
|
||||
// | |
|
||||
// | Smi
|
||||
// | /
|
||||
// Uninitialized.
|
||||
|
||||
class NumberInfo {
|
||||
public:
|
||||
enum Type {
|
||||
kUnknown = 0,
|
||||
kNumber = 1,
|
||||
kSmi = 3,
|
||||
kHeapNumber = 5,
|
||||
kUninitialized = 7
|
||||
};
|
||||
NumberInfo() { }
|
||||
|
||||
static inline NumberInfo Unknown();
|
||||
// We know it's a number of some sort.
|
||||
static inline NumberInfo Number();
|
||||
// We know it's signed or unsigned 32 bit integer.
|
||||
static inline NumberInfo Integer32();
|
||||
// We know it's a Smi.
|
||||
static inline NumberInfo Smi();
|
||||
// We know it's a heap number.
|
||||
static inline NumberInfo HeapNumber();
|
||||
// We haven't started collecting info yet.
|
||||
static inline NumberInfo Uninitialized();
|
||||
|
||||
// Return compact representation. Very sensitive to enum values below!
|
||||
int ThreeBitRepresentation() {
|
||||
ASSERT(type_ != kUninitializedType);
|
||||
int answer = type_ > 6 ? type_ -2 : type_;
|
||||
ASSERT(answer >= 0);
|
||||
ASSERT(answer <= 7);
|
||||
return answer;
|
||||
}
|
||||
|
||||
// Decode compact representation. Very sensitive to enum values below!
|
||||
static NumberInfo ExpandedRepresentation(int three_bit_representation) {
|
||||
Type t = static_cast<Type>(three_bit_representation >= 6 ?
|
||||
three_bit_representation + 2 :
|
||||
three_bit_representation);
|
||||
ASSERT(t == kUnknownType ||
|
||||
t == kNumberType ||
|
||||
t == kInteger32Type ||
|
||||
t == kSmiType ||
|
||||
t == kHeapNumberType);
|
||||
return NumberInfo(t);
|
||||
}
|
||||
|
||||
int ToInt() {
|
||||
return type_;
|
||||
}
|
||||
|
||||
static NumberInfo FromInt(int bit_representation) {
|
||||
Type t = static_cast<Type>(bit_representation);
|
||||
ASSERT(t == kUnknownType ||
|
||||
t == kNumberType ||
|
||||
t == kInteger32Type ||
|
||||
t == kSmiType ||
|
||||
t == kHeapNumberType);
|
||||
return NumberInfo(t);
|
||||
}
|
||||
|
||||
// Return the weakest (least precise) common type.
|
||||
static Type Combine(Type a, Type b) {
|
||||
// Make use of the order of enum values.
|
||||
return static_cast<Type>(a & b);
|
||||
static NumberInfo Combine(NumberInfo a, NumberInfo b) {
|
||||
return NumberInfo(static_cast<Type>(a.type_ & b.type_));
|
||||
}
|
||||
|
||||
static bool IsNumber(Type a) {
|
||||
ASSERT(a != kUninitialized);
|
||||
return ((a & kNumber) != 0);
|
||||
inline bool IsUnknown() {
|
||||
return type_ == kUnknownType;
|
||||
}
|
||||
|
||||
static const char* ToString(Type a) {
|
||||
switch (a) {
|
||||
case kUnknown: return "UnknownType";
|
||||
case kNumber: return "NumberType";
|
||||
case kSmi: return "SmiType";
|
||||
case kHeapNumber: return "HeapNumberType";
|
||||
case kUninitialized:
|
||||
inline bool IsNumber() {
|
||||
ASSERT(type_ != kUninitializedType);
|
||||
return ((type_ & kNumberType) == kNumberType);
|
||||
}
|
||||
|
||||
inline bool IsSmi() {
|
||||
ASSERT(type_ != kUninitializedType);
|
||||
return ((type_ & kSmiType) == kSmiType);
|
||||
}
|
||||
|
||||
inline bool IsInteger32() {
|
||||
ASSERT(type_ != kUninitializedType);
|
||||
return ((type_ & kInteger32Type) == kInteger32Type);
|
||||
}
|
||||
|
||||
inline bool IsHeapNumber() {
|
||||
ASSERT(type_ != kUninitializedType);
|
||||
return ((type_ & kHeapNumberType) == kHeapNumberType);
|
||||
}
|
||||
|
||||
inline bool IsUninitialized() {
|
||||
return type_ == kUninitializedType;
|
||||
}
|
||||
|
||||
const char* ToString() {
|
||||
switch (type_) {
|
||||
case kUnknownType: return "UnknownType";
|
||||
case kNumberType: return "NumberType";
|
||||
case kSmiType: return "SmiType";
|
||||
case kHeapNumberType: return "HeapNumberType";
|
||||
case kInteger32Type: return "Integer32Type";
|
||||
case kUninitializedType:
|
||||
UNREACHABLE();
|
||||
return "UninitializedType";
|
||||
}
|
||||
UNREACHABLE();
|
||||
return "Unreachable code";
|
||||
}
|
||||
|
||||
private:
|
||||
enum Type {
|
||||
kUnknownType = 0,
|
||||
kNumberType = 1,
|
||||
kInteger32Type = 3,
|
||||
kSmiType = 7,
|
||||
kHeapNumberType = 9,
|
||||
kUninitializedType = 15
|
||||
};
|
||||
explicit inline NumberInfo(Type t) : type_(t) { }
|
||||
|
||||
Type type_;
|
||||
};
|
||||
|
||||
|
||||
NumberInfo NumberInfo::Unknown() {
|
||||
return NumberInfo(kUnknownType);
|
||||
}
|
||||
|
||||
|
||||
NumberInfo NumberInfo::Number() {
|
||||
return NumberInfo(kNumberType);
|
||||
}
|
||||
|
||||
|
||||
NumberInfo NumberInfo::Integer32() {
|
||||
return NumberInfo(kInteger32Type);
|
||||
}
|
||||
|
||||
|
||||
NumberInfo NumberInfo::Smi() {
|
||||
return NumberInfo(kSmiType);
|
||||
}
|
||||
|
||||
|
||||
NumberInfo NumberInfo::HeapNumber() {
|
||||
return NumberInfo(kHeapNumberType);
|
||||
}
|
||||
|
||||
|
||||
NumberInfo NumberInfo::Uninitialized() {
|
||||
return NumberInfo(kUninitializedType);
|
||||
}
|
||||
|
||||
} } // namespace v8::internal
|
||||
|
||||
#endif // V8_NUMBER_INFO_H_
|
||||
|
@ -103,6 +103,45 @@ void RegisterAllocator::Unuse(Register reg) {
|
||||
registers_.Unuse(ToNumber(reg));
|
||||
}
|
||||
|
||||
|
||||
NumberInfo Result::number_info() const {
|
||||
ASSERT(is_valid());
|
||||
if (!is_constant()) {
|
||||
return NumberInfo::FromInt(NumberInfoField::decode(value_));
|
||||
}
|
||||
Handle<Object> value = handle();
|
||||
if (value->IsSmi()) return NumberInfo::Smi();
|
||||
if (value->IsHeapNumber()) return NumberInfo::HeapNumber();
|
||||
return NumberInfo::Unknown();
|
||||
}
|
||||
|
||||
|
||||
void Result::set_number_info(NumberInfo info) {
|
||||
ASSERT(is_valid());
|
||||
value_ &= ~NumberInfoField::mask();
|
||||
value_ |= NumberInfoField::encode(info.ToInt());
|
||||
}
|
||||
|
||||
|
||||
bool Result::is_number() const {
|
||||
return number_info().IsNumber();
|
||||
}
|
||||
|
||||
|
||||
bool Result::is_smi() const {
|
||||
return number_info().IsSmi();
|
||||
}
|
||||
|
||||
|
||||
bool Result::is_integer32() const {
|
||||
return number_info().IsInteger32();
|
||||
}
|
||||
|
||||
|
||||
bool Result::is_heap_number() const {
|
||||
return number_info().IsHeapNumber();
|
||||
}
|
||||
|
||||
} } // namespace v8::internal
|
||||
|
||||
#endif // V8_REGISTER_ALLOCATOR_INL_H_
|
||||
|
@ -38,11 +38,11 @@ namespace internal {
|
||||
// Result implementation.
|
||||
|
||||
|
||||
Result::Result(Register reg, NumberInfo::Type info) {
|
||||
Result::Result(Register reg, NumberInfo info) {
|
||||
ASSERT(reg.is_valid() && !RegisterAllocator::IsReserved(reg));
|
||||
CodeGeneratorScope::Current()->allocator()->Use(reg);
|
||||
value_ = TypeField::encode(REGISTER)
|
||||
| NumberInfoField::encode(info)
|
||||
| NumberInfoField::encode(info.ToInt())
|
||||
| DataField::encode(reg.code_);
|
||||
}
|
||||
|
||||
@ -53,23 +53,6 @@ Result::ZoneObjectList* Result::ConstantList() {
|
||||
}
|
||||
|
||||
|
||||
NumberInfo::Type Result::number_info() {
|
||||
ASSERT(is_valid());
|
||||
if (!is_constant()) return NumberInfoField::decode(value_);
|
||||
Handle<Object> value = handle();
|
||||
if (value->IsSmi()) return NumberInfo::kSmi;
|
||||
if (value->IsHeapNumber()) return NumberInfo::kHeapNumber;
|
||||
return NumberInfo::kUnknown;
|
||||
}
|
||||
|
||||
|
||||
void Result::set_number_info(NumberInfo::Type info) {
|
||||
ASSERT(is_valid());
|
||||
value_ = value_ & ~NumberInfoField::mask();
|
||||
value_ = value_ | NumberInfoField::encode(info);
|
||||
}
|
||||
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// RegisterAllocator implementation.
|
||||
|
||||
|
@ -65,12 +65,12 @@ class Result BASE_EMBEDDED {
|
||||
Result() { invalidate(); }
|
||||
|
||||
// Construct a register Result.
|
||||
explicit Result(Register reg, NumberInfo::Type info = NumberInfo::kUnknown);
|
||||
explicit Result(Register reg, NumberInfo info = NumberInfo::Unknown());
|
||||
|
||||
// Construct a Result whose value is a compile-time constant.
|
||||
explicit Result(Handle<Object> value) {
|
||||
value_ = TypeField::encode(CONSTANT)
|
||||
| NumberInfoField::encode(NumberInfo::kUninitialized)
|
||||
| NumberInfoField::encode(NumberInfo::Uninitialized().ToInt())
|
||||
| DataField::encode(ConstantList()->length());
|
||||
ConstantList()->Add(value);
|
||||
}
|
||||
@ -101,13 +101,12 @@ class Result BASE_EMBEDDED {
|
||||
|
||||
void invalidate() { value_ = TypeField::encode(INVALID); }
|
||||
|
||||
NumberInfo::Type number_info();
|
||||
void set_number_info(NumberInfo::Type info);
|
||||
bool is_number() {
|
||||
return (number_info() & NumberInfo::kNumber) != 0;
|
||||
}
|
||||
bool is_smi() { return number_info() == NumberInfo::kSmi; }
|
||||
bool is_heap_number() { return number_info() == NumberInfo::kHeapNumber; }
|
||||
inline NumberInfo number_info() const;
|
||||
inline void set_number_info(NumberInfo info);
|
||||
inline bool is_number() const;
|
||||
inline bool is_smi() const;
|
||||
inline bool is_integer32() const;
|
||||
inline bool is_heap_number() const;
|
||||
|
||||
bool is_valid() const { return type() != INVALID; }
|
||||
bool is_register() const { return type() == REGISTER; }
|
||||
@ -140,8 +139,8 @@ class Result BASE_EMBEDDED {
|
||||
uint32_t value_;
|
||||
|
||||
class TypeField: public BitField<Type, 0, 2> {};
|
||||
class NumberInfoField : public BitField<NumberInfo::Type, 2, 3> {};
|
||||
class DataField: public BitField<uint32_t, 5, 32 - 5> {};
|
||||
class NumberInfoField : public BitField<int, 2, 4> {};
|
||||
class DataField: public BitField<uint32_t, 6, 32 - 6> {};
|
||||
|
||||
inline void CopyTo(Result* destination) const;
|
||||
|
||||
|
@ -40,7 +40,7 @@ VirtualFrame::VirtualFrame()
|
||||
: elements_(parameter_count() + local_count() + kPreallocatedElements),
|
||||
stack_pointer_(parameter_count() + 1) { // 0-based index of TOS.
|
||||
for (int i = 0; i <= stack_pointer_; i++) {
|
||||
elements_.Add(FrameElement::MemoryElement(NumberInfo::kUnknown));
|
||||
elements_.Add(FrameElement::MemoryElement(NumberInfo::Unknown()));
|
||||
}
|
||||
for (int i = 0; i < RegisterAllocator::kNumRegisters; i++) {
|
||||
register_locations_[i] = kIllegalIndex;
|
||||
@ -65,7 +65,7 @@ void VirtualFrame::PushFrameSlotAt(int index) {
|
||||
}
|
||||
|
||||
|
||||
void VirtualFrame::Push(Register reg, NumberInfo::Type info) {
|
||||
void VirtualFrame::Push(Register reg, NumberInfo info) {
|
||||
if (is_used(reg)) {
|
||||
int index = register_location(reg);
|
||||
FrameElement element = CopyElementAt(index, info);
|
||||
|
@ -43,7 +43,7 @@ namespace internal {
|
||||
// not conflict with the existing type information and must be equally or
|
||||
// more precise. The default parameter value kUninitialized means that there
|
||||
// is no additional information.
|
||||
FrameElement VirtualFrame::CopyElementAt(int index, NumberInfo::Type info) {
|
||||
FrameElement VirtualFrame::CopyElementAt(int index, NumberInfo info) {
|
||||
ASSERT(index >= 0);
|
||||
ASSERT(index < element_count());
|
||||
|
||||
@ -74,14 +74,14 @@ FrameElement VirtualFrame::CopyElementAt(int index, NumberInfo::Type info) {
|
||||
result.set_index(index);
|
||||
elements_[index].set_copied();
|
||||
// Update backing element's number information.
|
||||
NumberInfo::Type existing = elements_[index].number_info();
|
||||
ASSERT(existing != NumberInfo::kUninitialized);
|
||||
NumberInfo existing = elements_[index].number_info();
|
||||
ASSERT(!existing.IsUninitialized());
|
||||
// Assert that the new type information (a) does not conflict with the
|
||||
// existing one and (b) is equally or more precise.
|
||||
ASSERT((info == NumberInfo::kUninitialized) ||
|
||||
(existing | info) != NumberInfo::kUninitialized);
|
||||
ASSERT(existing <= info);
|
||||
elements_[index].set_number_info(info != NumberInfo::kUninitialized
|
||||
ASSERT((info.ToInt() & existing.ToInt()) == existing.ToInt());
|
||||
ASSERT((info.ToInt() | existing.ToInt()) == info.ToInt());
|
||||
|
||||
elements_[index].set_number_info(!info.IsUninitialized()
|
||||
? info
|
||||
: existing);
|
||||
break;
|
||||
@ -104,7 +104,7 @@ void VirtualFrame::Adjust(int count) {
|
||||
ASSERT(stack_pointer_ == element_count() - 1);
|
||||
|
||||
for (int i = 0; i < count; i++) {
|
||||
elements_.Add(FrameElement::MemoryElement(NumberInfo::kUnknown));
|
||||
elements_.Add(FrameElement::MemoryElement(NumberInfo::Unknown()));
|
||||
}
|
||||
stack_pointer_ += count;
|
||||
}
|
||||
@ -152,7 +152,7 @@ void VirtualFrame::SpillElementAt(int index) {
|
||||
SyncElementAt(index);
|
||||
// Number type information is preserved.
|
||||
// Copies get their number information from their backing element.
|
||||
NumberInfo::Type info;
|
||||
NumberInfo info;
|
||||
if (!elements_[index].is_copy()) {
|
||||
info = elements_[index].number_info();
|
||||
} else {
|
||||
|
@ -5280,7 +5280,7 @@ void CodeGenerator::GenericBinaryOperation(Token::Value op,
|
||||
}
|
||||
|
||||
// Get number type of left and right sub-expressions.
|
||||
NumberInfo::Type operands_type =
|
||||
NumberInfo operands_type =
|
||||
NumberInfo::Combine(left.number_info(), right.number_info());
|
||||
|
||||
Result answer;
|
||||
@ -5316,7 +5316,7 @@ void CodeGenerator::GenericBinaryOperation(Token::Value op,
|
||||
// Set NumberInfo of result according to the operation performed.
|
||||
// We rely on the fact that smis have a 32 bit payload on x64.
|
||||
ASSERT(kSmiValueSize == 32);
|
||||
NumberInfo::Type result_type = NumberInfo::kUnknown;
|
||||
NumberInfo result_type = NumberInfo::Unknown();
|
||||
switch (op) {
|
||||
case Token::COMMA:
|
||||
result_type = right.number_info();
|
||||
@ -5330,32 +5330,32 @@ void CodeGenerator::GenericBinaryOperation(Token::Value op,
|
||||
case Token::BIT_XOR:
|
||||
case Token::BIT_AND:
|
||||
// Result is always a smi.
|
||||
result_type = NumberInfo::kSmi;
|
||||
result_type = NumberInfo::Smi();
|
||||
break;
|
||||
case Token::SAR:
|
||||
case Token::SHL:
|
||||
// Result is always a smi.
|
||||
result_type = NumberInfo::kSmi;
|
||||
result_type = NumberInfo::Smi();
|
||||
break;
|
||||
case Token::SHR:
|
||||
// Result of x >>> y is always a smi if y >= 1, otherwise a number.
|
||||
result_type = (right.is_constant() && right.handle()->IsSmi()
|
||||
&& Smi::cast(*right.handle())->value() >= 1)
|
||||
? NumberInfo::kSmi
|
||||
: NumberInfo::kNumber;
|
||||
? NumberInfo::Smi()
|
||||
: NumberInfo::Number();
|
||||
break;
|
||||
case Token::ADD:
|
||||
// Result could be a string or a number. Check types of inputs.
|
||||
result_type = NumberInfo::IsNumber(operands_type)
|
||||
? NumberInfo::kNumber
|
||||
: NumberInfo::kUnknown;
|
||||
result_type = operands_type.IsNumber()
|
||||
? NumberInfo::Number()
|
||||
: NumberInfo::Unknown();
|
||||
break;
|
||||
case Token::SUB:
|
||||
case Token::MUL:
|
||||
case Token::DIV:
|
||||
case Token::MOD:
|
||||
// Result is always a number.
|
||||
result_type = NumberInfo::kNumber;
|
||||
result_type = NumberInfo::Number();
|
||||
break;
|
||||
default:
|
||||
UNREACHABLE();
|
||||
@ -8332,7 +8332,7 @@ const char* GenericBinaryOpStub::GetName() {
|
||||
args_in_registers_ ? "RegArgs" : "StackArgs",
|
||||
args_reversed_ ? "_R" : "",
|
||||
use_sse3_ ? "SSE3" : "SSE2",
|
||||
NumberInfo::ToString(operands_type_));
|
||||
operands_type_.ToString());
|
||||
return name_;
|
||||
}
|
||||
|
||||
@ -8656,7 +8656,7 @@ void GenericBinaryOpStub::Generate(MacroAssembler* masm) {
|
||||
case Token::DIV: {
|
||||
// rax: y
|
||||
// rdx: x
|
||||
if (NumberInfo::IsNumber(operands_type_)) {
|
||||
if (operands_type_.IsNumber()) {
|
||||
if (FLAG_debug_code) {
|
||||
// Assert at runtime that inputs are only numbers.
|
||||
__ AbortIfNotNumber(rdx, "GenericBinaryOpStub operand not a number.");
|
||||
|
@ -661,7 +661,7 @@ class GenericBinaryOpStub: public CodeStub {
|
||||
GenericBinaryOpStub(Token::Value op,
|
||||
OverwriteMode mode,
|
||||
GenericBinaryFlags flags,
|
||||
NumberInfo::Type operands_type = NumberInfo::kUnknown)
|
||||
NumberInfo operands_type = NumberInfo::Unknown())
|
||||
: op_(op),
|
||||
mode_(mode),
|
||||
flags_(flags),
|
||||
@ -693,7 +693,7 @@ class GenericBinaryOpStub: public CodeStub {
|
||||
bool args_reversed_; // Left and right argument are swapped.
|
||||
bool use_sse3_;
|
||||
char* name_;
|
||||
NumberInfo::Type operands_type_;
|
||||
NumberInfo operands_type_;
|
||||
|
||||
const char* GetName();
|
||||
|
||||
@ -707,7 +707,7 @@ class GenericBinaryOpStub: public CodeStub {
|
||||
static_cast<int>(flags_),
|
||||
static_cast<int>(args_in_registers_),
|
||||
static_cast<int>(args_reversed_),
|
||||
NumberInfo::ToString(operands_type_));
|
||||
operands_type_.ToString());
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -718,7 +718,7 @@ class GenericBinaryOpStub: public CodeStub {
|
||||
class ArgsInRegistersBits: public BitField<bool, 10, 1> {};
|
||||
class ArgsReversedBits: public BitField<bool, 11, 1> {};
|
||||
class FlagBits: public BitField<GenericBinaryFlags, 12, 1> {};
|
||||
class NumberInfoBits: public BitField<NumberInfo::Type, 13, 3> {};
|
||||
class NumberInfoBits: public BitField<int, 13, 3> {};
|
||||
|
||||
Major MajorKey() { return GenericBinaryOp; }
|
||||
int MinorKey() {
|
||||
@ -729,7 +729,7 @@ class GenericBinaryOpStub: public CodeStub {
|
||||
| SSE3Bits::encode(use_sse3_)
|
||||
| ArgsInRegistersBits::encode(args_in_registers_)
|
||||
| ArgsReversedBits::encode(args_reversed_)
|
||||
| NumberInfoBits::encode(operands_type_);
|
||||
| NumberInfoBits::encode(operands_type_.ThreeBitRepresentation());
|
||||
}
|
||||
|
||||
void Generate(MacroAssembler* masm);
|
||||
|
@ -177,7 +177,7 @@ void VirtualFrame::EmitPop(const Operand& operand) {
|
||||
}
|
||||
|
||||
|
||||
void VirtualFrame::EmitPush(Register reg, NumberInfo::Type info) {
|
||||
void VirtualFrame::EmitPush(Register reg, NumberInfo info) {
|
||||
ASSERT(stack_pointer_ == element_count() - 1);
|
||||
elements_.Add(FrameElement::MemoryElement(info));
|
||||
stack_pointer_++;
|
||||
@ -185,7 +185,7 @@ void VirtualFrame::EmitPush(Register reg, NumberInfo::Type info) {
|
||||
}
|
||||
|
||||
|
||||
void VirtualFrame::EmitPush(const Operand& operand, NumberInfo::Type info) {
|
||||
void VirtualFrame::EmitPush(const Operand& operand, NumberInfo info) {
|
||||
ASSERT(stack_pointer_ == element_count() - 1);
|
||||
elements_.Add(FrameElement::MemoryElement(info));
|
||||
stack_pointer_++;
|
||||
@ -193,7 +193,7 @@ void VirtualFrame::EmitPush(const Operand& operand, NumberInfo::Type info) {
|
||||
}
|
||||
|
||||
|
||||
void VirtualFrame::EmitPush(Immediate immediate, NumberInfo::Type info) {
|
||||
void VirtualFrame::EmitPush(Immediate immediate, NumberInfo info) {
|
||||
ASSERT(stack_pointer_ == element_count() - 1);
|
||||
elements_.Add(FrameElement::MemoryElement(info));
|
||||
stack_pointer_++;
|
||||
@ -203,7 +203,7 @@ void VirtualFrame::EmitPush(Immediate immediate, NumberInfo::Type info) {
|
||||
|
||||
void VirtualFrame::EmitPush(Smi* smi_value) {
|
||||
ASSERT(stack_pointer_ == element_count() - 1);
|
||||
elements_.Add(FrameElement::MemoryElement(NumberInfo::kSmi));
|
||||
elements_.Add(FrameElement::MemoryElement(NumberInfo::Smi()));
|
||||
stack_pointer_++;
|
||||
__ Push(smi_value);
|
||||
}
|
||||
@ -211,11 +211,11 @@ void VirtualFrame::EmitPush(Smi* smi_value) {
|
||||
|
||||
void VirtualFrame::EmitPush(Handle<Object> value) {
|
||||
ASSERT(stack_pointer_ == element_count() - 1);
|
||||
NumberInfo::Type info = NumberInfo::kUnknown;
|
||||
NumberInfo info = NumberInfo::Unknown();
|
||||
if (value->IsSmi()) {
|
||||
info = NumberInfo::kSmi;
|
||||
info = NumberInfo::Smi();
|
||||
} else if (value->IsHeapNumber()) {
|
||||
info = NumberInfo::kHeapNumber;
|
||||
info = NumberInfo::HeapNumber();
|
||||
}
|
||||
elements_.Add(FrameElement::MemoryElement(info));
|
||||
stack_pointer_++;
|
||||
@ -223,7 +223,7 @@ void VirtualFrame::EmitPush(Handle<Object> value) {
|
||||
}
|
||||
|
||||
|
||||
void VirtualFrame::EmitPush(Heap::RootListIndex index, NumberInfo::Type info) {
|
||||
void VirtualFrame::EmitPush(Heap::RootListIndex index, NumberInfo info) {
|
||||
ASSERT(stack_pointer_ == element_count() - 1);
|
||||
elements_.Add(FrameElement::MemoryElement(info));
|
||||
stack_pointer_++;
|
||||
@ -480,7 +480,7 @@ void VirtualFrame::MakeMergable() {
|
||||
if (element.is_constant() || element.is_copy()) {
|
||||
if (element.is_synced()) {
|
||||
// Just spill.
|
||||
elements_[i] = FrameElement::MemoryElement(NumberInfo::kUnknown);
|
||||
elements_[i] = FrameElement::MemoryElement(NumberInfo::Unknown());
|
||||
} else {
|
||||
// Allocate to a register.
|
||||
FrameElement backing_element; // Invalid if not a copy.
|
||||
@ -492,7 +492,7 @@ void VirtualFrame::MakeMergable() {
|
||||
elements_[i] =
|
||||
FrameElement::RegisterElement(fresh.reg(),
|
||||
FrameElement::NOT_SYNCED,
|
||||
NumberInfo::kUnknown);
|
||||
NumberInfo::Unknown());
|
||||
Use(fresh.reg(), i);
|
||||
|
||||
// Emit a move.
|
||||
@ -521,7 +521,7 @@ void VirtualFrame::MakeMergable() {
|
||||
// The copy flag is not relied on before the end of this loop,
|
||||
// including when registers are spilled.
|
||||
elements_[i].clear_copied();
|
||||
elements_[i].set_number_info(NumberInfo::kUnknown);
|
||||
elements_[i].set_number_info(NumberInfo::Unknown());
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -728,7 +728,7 @@ Result VirtualFrame::Pop() {
|
||||
ASSERT(element.is_valid());
|
||||
|
||||
// Get number type information of the result.
|
||||
NumberInfo::Type info;
|
||||
NumberInfo info;
|
||||
if (!element.is_copy()) {
|
||||
info = element.number_info();
|
||||
} else {
|
||||
|
@ -83,7 +83,7 @@ class VirtualFrame : public ZoneObject {
|
||||
|
||||
// Create a duplicate of an existing valid frame element.
|
||||
FrameElement CopyElementAt(int index,
|
||||
NumberInfo::Type info = NumberInfo::kUninitialized);
|
||||
NumberInfo info = NumberInfo::Uninitialized());
|
||||
|
||||
// The number of elements on the virtual frame.
|
||||
int element_count() { return elements_.length(); }
|
||||
@ -383,19 +383,19 @@ class VirtualFrame : public ZoneObject {
|
||||
// Push an element on top of the expression stack and emit a
|
||||
// corresponding push instruction.
|
||||
void EmitPush(Register reg,
|
||||
NumberInfo::Type info = NumberInfo::kUnknown);
|
||||
NumberInfo info = NumberInfo::Unknown());
|
||||
void EmitPush(const Operand& operand,
|
||||
NumberInfo::Type info = NumberInfo::kUnknown);
|
||||
NumberInfo info = NumberInfo::Unknown());
|
||||
void EmitPush(Heap::RootListIndex index,
|
||||
NumberInfo::Type info = NumberInfo::kUnknown);
|
||||
NumberInfo info = NumberInfo::Unknown());
|
||||
void EmitPush(Immediate immediate,
|
||||
NumberInfo::Type info = NumberInfo::kUnknown);
|
||||
NumberInfo info = NumberInfo::Unknown());
|
||||
void EmitPush(Smi* value);
|
||||
// Uses kScratchRegister, emits appropriate relocation info.
|
||||
void EmitPush(Handle<Object> value);
|
||||
|
||||
// Push an element on the virtual frame.
|
||||
inline void Push(Register reg, NumberInfo::Type info = NumberInfo::kUnknown);
|
||||
inline void Push(Register reg, NumberInfo info = NumberInfo::Unknown());
|
||||
inline void Push(Handle<Object> value);
|
||||
inline void Push(Smi* value);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user