void VirtualFrame::EmitPush(Register reg) {
ASSERT(stack_pointer_ == element_count() - 1);
- elements_.Add(FrameElement::MemoryElement(NumberInfo::Unknown()));
+ elements_.Add(FrameElement::MemoryElement(TypeInfo::Unknown()));
stack_pointer_++;
__ push(reg);
}
// Create a duplicate of an existing valid frame element.
FrameElement CopyElementAt(int index,
- NumberInfo info = NumberInfo::Unknown());
+ TypeInfo info = TypeInfo::Unknown());
// The number of elements on the virtual frame.
int element_count() { return elements_.length(); }
void EmitPushMultiple(int count, int src_regs);
// Push an element on the virtual frame.
- inline void Push(Register reg, NumberInfo info = NumberInfo::Unknown());
+ inline void Push(Register reg, TypeInfo info = TypeInfo::Unknown());
inline void Push(Handle<Object> value);
inline void Push(Smi* value);
// the frame. Nip(k) is equivalent to x = Pop(), Drop(k), Push(x).
inline void Nip(int num_dropped);
- inline void SetTypeForLocalAt(int index, NumberInfo info);
- inline void SetTypeForParamAt(int index, NumberInfo info);
+ inline void SetTypeForLocalAt(int index, TypeInfo info);
+ inline void SetTypeForParamAt(int index, TypeInfo info);
private:
static const int kLocal0Offset = JavaScriptFrameConstants::kLocal0Offset;
#include "ast.h"
#include "code-stubs.h"
#include "runtime.h"
-#include "number-info.h"
+#include "type-info.h"
// Include the declaration of the architecture defined class CodeGenerator.
// The contract to the shared code is that the the CodeGenerator is a subclass
#ifndef V8_FRAME_ELEMENT_H_
#define V8_FRAME_ELEMENT_H_
-#include "number-info-inl.h"
+#include "type-info-inl.h"
#include "macro-assembler.h"
#include "zone.h"
SYNCED
};
- inline NumberInfo number_info() {
- // Copied elements do not have number info. Instead
+ inline TypeInfo type_info() {
+ // Copied elements do not have type info. Instead
// we have to inspect their backing element in the frame.
ASSERT(!is_copy());
- return NumberInfo::FromInt(NumberInfoField::decode(value_));
+ return TypeInfo::FromInt(TypeInfoField::decode(value_));
}
- inline void set_number_info(NumberInfo info) {
- // Copied elements do not have number info. Instead
+ inline void set_type_info(TypeInfo info) {
+ // Copied elements do not have type info. Instead
// we have to inspect their backing element in the frame.
ASSERT(!is_copy());
- value_ = value_ & ~NumberInfoField::mask();
- value_ = value_ | NumberInfoField::encode(info.ToInt());
+ value_ = value_ & ~TypeInfoField::mask();
+ value_ = value_ | TypeInfoField::encode(info.ToInt());
}
// The default constructor creates an invalid frame element.
value_ = TypeField::encode(INVALID)
| CopiedField::encode(false)
| SyncedField::encode(false)
- | NumberInfoField::encode(NumberInfo::Uninitialized().ToInt())
+ | TypeInfoField::encode(TypeInfo::Uninitialized().ToInt())
| DataField::encode(0);
}
}
// Factory function to construct an in-memory frame element.
- static FrameElement MemoryElement(NumberInfo info) {
+ static FrameElement MemoryElement(TypeInfo info) {
FrameElement result(MEMORY, no_reg, SYNCED, info);
return result;
}
// Factory function to construct an in-register frame element.
static FrameElement RegisterElement(Register reg,
SyncFlag is_synced,
- NumberInfo info) {
+ TypeInfo info) {
return FrameElement(REGISTER, reg, is_synced, info);
}
// compile time.
static FrameElement ConstantElement(Handle<Object> value,
SyncFlag is_synced) {
- NumberInfo info = NumberInfo::TypeFromValue(value);
+ TypeInfo info = TypeInfo::TypeFromValue(value);
FrameElement result(value, is_synced, info);
return result;
}
FrameElement(Type type,
Register reg,
SyncFlag is_synced,
- NumberInfo info) {
+ TypeInfo info) {
value_ = TypeField::encode(type)
| CopiedField::encode(false)
| SyncedField::encode(is_synced != NOT_SYNCED)
- | NumberInfoField::encode(info.ToInt())
+ | TypeInfoField::encode(info.ToInt())
| DataField::encode(reg.code_ > 0 ? reg.code_ : 0);
}
// Used to construct constant elements.
- FrameElement(Handle<Object> value, SyncFlag is_synced, NumberInfo info) {
+ FrameElement(Handle<Object> value, SyncFlag is_synced, TypeInfo info) {
value_ = TypeField::encode(CONSTANT)
| CopiedField::encode(false)
| SyncedField::encode(is_synced != NOT_SYNCED)
- | NumberInfoField::encode(info.ToInt())
+ | TypeInfoField::encode(info.ToInt())
| DataField::encode(ConstantList()->length());
ConstantList()->Add(value);
}
class CopiedField: public BitField<bool, 3, 1> {};
class SyncedField: public BitField<bool, 4, 1> {};
class UntaggedInt32Field: public BitField<bool, 5, 1> {};
- class NumberInfoField: public BitField<int, 6, 6> {};
+ class TypeInfoField: public BitField<int, 6, 6> {};
class DataField: public BitField<uint32_t, 12, 32 - 12> {};
friend class VirtualFrame;
dest->Split(not_zero);
} else if (value.is_number()) {
Comment cmnt(masm_, "ONLY_NUMBER");
- // Fast case if NumberInfo indicates only numbers.
+ // Fast case if TypeInfo indicates only numbers.
if (FLAG_debug_code) {
__ AbortIfNotNumber(value.reg());
}
// Takes the operands in edx and eax and loads them as integers in eax
// and ecx.
static void LoadAsIntegers(MacroAssembler* masm,
- NumberInfo number_info,
+ TypeInfo type_info,
bool use_sse3,
Label* operand_conversion_failure);
static void LoadNumbersAsIntegers(MacroAssembler* masm,
- NumberInfo number_info,
+ TypeInfo type_info,
bool use_sse3,
Label* operand_conversion_failure);
static void LoadUnknownsAsIntegers(MacroAssembler* masm,
Register dst,
Register left,
Register right,
- NumberInfo left_info,
- NumberInfo right_info,
+ TypeInfo left_info,
+ TypeInfo right_info,
OverwriteMode mode)
: op_(op), dst_(dst), left_(left), right_(right),
left_info_(left_info), right_info_(right_info), mode_(mode) {
Register dst_;
Register left_;
Register right_;
- NumberInfo left_info_;
- NumberInfo right_info_;
+ TypeInfo left_info_;
+ TypeInfo right_info_;
OverwriteMode mode_;
};
GenericBinaryOpStub stub(op_,
mode_,
NO_SMI_CODE_IN_STUB,
- NumberInfo::Combine(left_info_, right_info_));
+ TypeInfo::Combine(left_info_, right_info_));
stub.GenerateCall(masm_, left_, right_);
if (!dst_.is(eax)) __ mov(dst_, eax);
__ bind(&done);
}
-static NumberInfo CalculateNumberInfo(NumberInfo operands_type,
+static TypeInfo CalculateTypeInfo(TypeInfo operands_type,
Token::Value op,
const Result& right,
const Result& left) {
- // Set NumberInfo of result according to the operation performed.
+ // Set TypeInfo of result according to the operation performed.
// Rely on the fact that smis have a 31 bit payload on ia32.
ASSERT(kSmiValueSize == 31);
switch (op) {
case Token::COMMA:
- return right.number_info();
+ return right.type_info();
case Token::OR:
case Token::AND:
// Result type can be either of the two input types.
// Anding with positive Smis will give you a Smi.
if (right.is_constant() && right.handle()->IsSmi() &&
Smi::cast(*right.handle())->value() >= 0) {
- return NumberInfo::Smi();
+ return TypeInfo::Smi();
} else if (left.is_constant() && left.handle()->IsSmi() &&
Smi::cast(*left.handle())->value() >= 0) {
- return NumberInfo::Smi();
+ return TypeInfo::Smi();
}
return (operands_type.IsSmi())
- ? NumberInfo::Smi()
- : NumberInfo::Integer32();
+ ? TypeInfo::Smi()
+ : TypeInfo::Integer32();
}
case Token::BIT_OR: {
// Oring with negative Smis will give you a Smi.
if (right.is_constant() && right.handle()->IsSmi() &&
Smi::cast(*right.handle())->value() < 0) {
- return NumberInfo::Smi();
+ return TypeInfo::Smi();
} else if (left.is_constant() && left.handle()->IsSmi() &&
Smi::cast(*left.handle())->value() < 0) {
- return NumberInfo::Smi();
+ return TypeInfo::Smi();
}
return (operands_type.IsSmi())
- ? NumberInfo::Smi()
- : NumberInfo::Integer32();
+ ? TypeInfo::Smi()
+ : TypeInfo::Integer32();
}
case Token::BIT_XOR:
// Result is always a 32 bit integer. Smi property of inputs is preserved.
return (operands_type.IsSmi())
- ? NumberInfo::Smi()
- : NumberInfo::Integer32();
+ ? TypeInfo::Smi()
+ : TypeInfo::Integer32();
case Token::SAR:
- if (left.is_smi()) return NumberInfo::Smi();
+ if (left.is_smi()) return TypeInfo::Smi();
// Result is a smi if we shift by a constant >= 1, otherwise an integer32.
return (right.is_constant() && right.handle()->IsSmi()
&& Smi::cast(*right.handle())->value() >= 1)
- ? NumberInfo::Smi()
- : NumberInfo::Integer32();
+ ? TypeInfo::Smi()
+ : TypeInfo::Integer32();
case Token::SHR:
// Result is a smi if we shift by a constant >= 2, otherwise an integer32.
return (right.is_constant() && right.handle()->IsSmi()
&& Smi::cast(*right.handle())->value() >= 2)
- ? NumberInfo::Smi()
- : NumberInfo::Integer32();
+ ? TypeInfo::Smi()
+ : TypeInfo::Integer32();
case Token::ADD:
if (operands_type.IsSmi()) {
// The Integer32 range is big enough to take the sum of any two Smis.
- return NumberInfo::Integer32();
+ return TypeInfo::Integer32();
} else {
// Result could be a string or a number. Check types of inputs.
return operands_type.IsNumber()
- ? NumberInfo::Number()
- : NumberInfo::Unknown();
+ ? TypeInfo::Number()
+ : TypeInfo::Unknown();
}
case Token::SHL:
- return NumberInfo::Integer32();
+ return TypeInfo::Integer32();
case Token::SUB:
// The Integer32 range is big enough to take the difference of any two
// Smis.
return (operands_type.IsSmi()) ?
- NumberInfo::Integer32() :
- NumberInfo::Number();
+ TypeInfo::Integer32() :
+ TypeInfo::Number();
case Token::MUL:
case Token::DIV:
case Token::MOD:
// Result is always a number.
- return NumberInfo::Number();
+ return TypeInfo::Number();
default:
UNREACHABLE();
}
UNREACHABLE();
- return NumberInfo::Unknown();
+ return TypeInfo::Unknown();
}
}
// Get number type of left and right sub-expressions.
- NumberInfo operands_type =
- NumberInfo::Combine(left.number_info(), right.number_info());
+ TypeInfo operands_type =
+ TypeInfo::Combine(left.type_info(), right.type_info());
- NumberInfo result_type = CalculateNumberInfo(operands_type, op, right, left);
+ TypeInfo result_type = CalculateTypeInfo(operands_type, op, right, left);
Result answer;
if (left_is_non_smi_constant || right_is_non_smi_constant) {
}
}
- answer.set_number_info(result_type);
+ answer.set_type_info(result_type);
frame_->Push(&answer);
}
static void CheckTwoForSminess(MacroAssembler* masm,
Register left, Register right, Register scratch,
- NumberInfo left_info, NumberInfo right_info,
+ TypeInfo left_info, TypeInfo right_info,
DeferredInlineBinaryOperation* deferred);
(op == Token::DIV) ? eax : edx,
left->reg(),
right->reg(),
- left->number_info(),
- right->number_info(),
+ left->type_info(),
+ right->type_info(),
overwrite_mode);
if (left->reg().is(right->reg())) {
__ test(left->reg(), Immediate(kSmiTagMask));
answer.reg(),
left->reg(),
ecx,
- left->number_info(),
- right->number_info(),
+ left->type_info(),
+ right->type_info(),
overwrite_mode);
Label do_op, left_nonsmi;
// If right is a smi we make a fast case if left is either a smi
// or a heapnumber.
- if (CpuFeatures::IsSupported(SSE2) && right->number_info().IsSmi()) {
+ if (CpuFeatures::IsSupported(SSE2) && right->type_info().IsSmi()) {
CpuFeatures::Scope use_sse2(SSE2);
__ mov(answer.reg(), left->reg());
// Fast case - both are actually smis.
- if (!left->number_info().IsSmi()) {
+ if (!left->type_info().IsSmi()) {
__ test(answer.reg(), Immediate(kSmiTagMask));
__ j(not_zero, &left_nonsmi);
} else {
deferred->Branch(negative);
} else {
CheckTwoForSminess(masm_, left->reg(), right->reg(), answer.reg(),
- left->number_info(), right->number_info(), deferred);
+ left->type_info(), right->type_info(), deferred);
// Untag both operands.
__ mov(answer.reg(), left->reg());
answer.reg(),
left->reg(),
right->reg(),
- left->number_info(),
- right->number_info(),
+ left->type_info(),
+ right->type_info(),
overwrite_mode);
CheckTwoForSminess(masm_, left->reg(), right->reg(), answer.reg(),
- left->number_info(), right->number_info(), deferred);
+ left->type_info(), right->type_info(), deferred);
__ mov(answer.reg(), left->reg());
switch (op) {
DeferredInlineSmiOperation(Token::Value op,
Register dst,
Register src,
- NumberInfo number_info,
+ TypeInfo type_info,
Smi* value,
OverwriteMode overwrite_mode)
: op_(op),
dst_(dst),
src_(src),
- number_info_(number_info),
+ type_info_(type_info),
value_(value),
overwrite_mode_(overwrite_mode) {
- if (number_info.IsSmi()) overwrite_mode_ = NO_OVERWRITE;
+ if (type_info.IsSmi()) overwrite_mode_ = NO_OVERWRITE;
set_comment("[ DeferredInlineSmiOperation");
}
Token::Value op_;
Register dst_;
Register src_;
- NumberInfo number_info_;
+ TypeInfo type_info_;
Smi* value_;
OverwriteMode overwrite_mode_;
};
op_,
overwrite_mode_,
(op_ == Token::MOD) ? NO_GENERIC_BINARY_FLAGS : NO_SMI_CODE_IN_STUB,
- NumberInfo::Combine(NumberInfo::Smi(), number_info_));
+ TypeInfo::Combine(TypeInfo::Smi(), type_info_));
stub.GenerateCall(masm_, src_, value_);
if (!dst_.is(eax)) __ mov(dst_, eax);
}
Register dst,
Smi* value,
Register src,
- NumberInfo number_info,
+ TypeInfo type_info,
OverwriteMode overwrite_mode)
: op_(op),
dst_(dst),
- number_info_(number_info),
+ type_info_(type_info),
value_(value),
src_(src),
overwrite_mode_(overwrite_mode) {
private:
Token::Value op_;
Register dst_;
- NumberInfo number_info_;
+ TypeInfo type_info_;
Smi* value_;
Register src_;
OverwriteMode overwrite_mode_;
op_,
overwrite_mode_,
NO_SMI_CODE_IN_STUB,
- NumberInfo::Combine(NumberInfo::Smi(), number_info_));
+ TypeInfo::Combine(TypeInfo::Smi(), type_info_));
igostub.GenerateCall(masm_, value_, src_);
if (!dst_.is(eax)) __ mov(dst_, eax);
}
class DeferredInlineSmiAdd: public DeferredCode {
public:
DeferredInlineSmiAdd(Register dst,
- NumberInfo number_info,
+ TypeInfo type_info,
Smi* value,
OverwriteMode overwrite_mode)
: dst_(dst),
- number_info_(number_info),
+ type_info_(type_info),
value_(value),
overwrite_mode_(overwrite_mode) {
- if (number_info_.IsSmi()) overwrite_mode_ = NO_OVERWRITE;
+ if (type_info_.IsSmi()) overwrite_mode_ = NO_OVERWRITE;
set_comment("[ DeferredInlineSmiAdd");
}
private:
Register dst_;
- NumberInfo number_info_;
+ TypeInfo type_info_;
Smi* value_;
OverwriteMode overwrite_mode_;
};
Token::ADD,
overwrite_mode_,
NO_SMI_CODE_IN_STUB,
- NumberInfo::Combine(NumberInfo::Smi(), number_info_));
+ TypeInfo::Combine(TypeInfo::Smi(), type_info_));
igostub.GenerateCall(masm_, dst_, value_);
if (!dst_.is(eax)) __ mov(dst_, eax);
}
class DeferredInlineSmiAddReversed: public DeferredCode {
public:
DeferredInlineSmiAddReversed(Register dst,
- NumberInfo number_info,
+ TypeInfo type_info,
Smi* value,
OverwriteMode overwrite_mode)
: dst_(dst),
- number_info_(number_info),
+ type_info_(type_info),
value_(value),
overwrite_mode_(overwrite_mode) {
set_comment("[ DeferredInlineSmiAddReversed");
private:
Register dst_;
- NumberInfo number_info_;
+ TypeInfo type_info_;
Smi* value_;
OverwriteMode overwrite_mode_;
};
Token::ADD,
overwrite_mode_,
NO_SMI_CODE_IN_STUB,
- NumberInfo::Combine(NumberInfo::Smi(), number_info_));
+ TypeInfo::Combine(TypeInfo::Smi(), type_info_));
igostub.GenerateCall(masm_, value_, dst_);
if (!dst_.is(eax)) __ mov(dst_, eax);
}
class DeferredInlineSmiSub: public DeferredCode {
public:
DeferredInlineSmiSub(Register dst,
- NumberInfo number_info,
+ TypeInfo type_info,
Smi* value,
OverwriteMode overwrite_mode)
: dst_(dst),
- number_info_(number_info),
+ type_info_(type_info),
value_(value),
overwrite_mode_(overwrite_mode) {
- if (number_info.IsSmi()) overwrite_mode_ = NO_OVERWRITE;
+ if (type_info.IsSmi()) overwrite_mode_ = NO_OVERWRITE;
set_comment("[ DeferredInlineSmiSub");
}
private:
Register dst_;
- NumberInfo number_info_;
+ TypeInfo type_info_;
Smi* value_;
OverwriteMode overwrite_mode_;
};
Token::SUB,
overwrite_mode_,
NO_SMI_CODE_IN_STUB,
- NumberInfo::Combine(NumberInfo::Smi(), number_info_));
+ TypeInfo::Combine(TypeInfo::Smi(), type_info_));
igostub.GenerateCall(masm_, dst_, value_);
if (!dst_.is(eax)) __ mov(dst_, eax);
}
DeferredCode* deferred = NULL;
if (reversed) {
deferred = new DeferredInlineSmiAddReversed(operand->reg(),
- operand->number_info(),
+ operand->type_info(),
smi_value,
overwrite_mode);
} else {
deferred = new DeferredInlineSmiAdd(operand->reg(),
- operand->number_info(),
+ operand->type_info(),
smi_value,
overwrite_mode);
}
__ add(Operand(operand->reg()), Immediate(value));
deferred->Branch(overflow);
- if (!operand->number_info().IsSmi()) {
+ if (!operand->type_info().IsSmi()) {
__ test(operand->reg(), Immediate(kSmiTagMask));
deferred->Branch(not_zero);
} else {
answer.reg(),
smi_value,
operand->reg(),
- operand->number_info(),
+ operand->type_info(),
overwrite_mode);
__ sub(answer.reg(), Operand(operand->reg()));
} else {
frame_->Spill(operand->reg());
answer = *operand;
deferred = new DeferredInlineSmiSub(operand->reg(),
- operand->number_info(),
+ operand->type_info(),
smi_value,
overwrite_mode);
__ sub(Operand(operand->reg()), Immediate(value));
}
deferred->Branch(overflow);
- if (!operand->number_info().IsSmi()) {
+ if (!operand->type_info().IsSmi()) {
__ test(answer.reg(), Immediate(kSmiTagMask));
deferred->Branch(not_zero);
} else {
int shift_value = int_value & 0x1f;
operand->ToRegister();
frame_->Spill(operand->reg());
- if (!operand->number_info().IsSmi()) {
+ if (!operand->type_info().IsSmi()) {
DeferredInlineSmiOperation* deferred =
new DeferredInlineSmiOperation(op,
operand->reg(),
operand->reg(),
- operand->number_info(),
+ operand->type_info(),
smi_value,
overwrite_mode);
__ test(operand->reg(), Immediate(kSmiTagMask));
new DeferredInlineSmiOperation(op,
answer.reg(),
operand->reg(),
- operand->number_info(),
+ operand->type_info(),
smi_value,
overwrite_mode);
- if (!operand->number_info().IsSmi()) {
+ if (!operand->type_info().IsSmi()) {
__ test(operand->reg(), Immediate(kSmiTagMask));
deferred->Branch(not_zero);
} else {
answer.reg(),
smi_value,
right.reg(),
- right.number_info(),
+ right.type_info(),
overwrite_mode);
__ mov(answer.reg(), Immediate(int_value));
__ sar(ecx, kSmiTagSize);
- if (!right.number_info().IsSmi()) {
+ if (!right.type_info().IsSmi()) {
deferred->Branch(carry);
} else {
if (FLAG_debug_code) __ AbortIfNotSmi(right.reg());
new DeferredInlineSmiOperation(op,
operand->reg(),
operand->reg(),
- operand->number_info(),
+ operand->type_info(),
smi_value,
overwrite_mode);
__ test(operand->reg(), Immediate(kSmiTagMask));
new DeferredInlineSmiOperation(op,
answer.reg(),
operand->reg(),
- operand->number_info(),
+ operand->type_info(),
smi_value,
overwrite_mode);
- if (!operand->number_info().IsSmi()) {
+ if (!operand->type_info().IsSmi()) {
__ test(operand->reg(), Immediate(kSmiTagMask));
deferred->Branch(not_zero);
} else {
operand->reg(),
smi_value,
operand->reg(),
- operand->number_info(),
+ operand->type_info(),
overwrite_mode);
} else {
deferred = new DeferredInlineSmiOperation(op,
operand->reg(),
operand->reg(),
- operand->number_info(),
+ operand->type_info(),
smi_value,
overwrite_mode);
}
- if (!operand->number_info().IsSmi()) {
+ if (!operand->type_info().IsSmi()) {
__ test(operand->reg(), Immediate(kSmiTagMask));
deferred->Branch(not_zero);
} else {
new DeferredInlineSmiOperation(op,
operand->reg(),
operand->reg(),
- operand->number_info(),
+ operand->type_info(),
smi_value,
overwrite_mode);
// Check that lowest log2(value) bits of operand are zero, and test
new DeferredInlineSmiOperation(op,
operand->reg(),
operand->reg(),
- operand->number_info(),
+ operand->type_info(),
smi_value,
overwrite_mode);
// Check for negative or non-Smi left hand side.
static bool CouldBeNaN(const Result& result) {
- if (result.number_info().IsSmi()) return false;
- if (result.number_info().IsInteger32()) return false;
+ if (result.type_info().IsSmi()) return false;
+ if (result.type_info().IsInteger32()) return false;
if (!result.is_constant()) return true;
if (!result.handle()->IsHeapNumber()) return false;
return isnan(HeapNumber::cast(*result.handle())->value());
}
-void CodeGenerator::SetTypeForStackSlot(Slot* slot, NumberInfo info) {
+void CodeGenerator::SetTypeForStackSlot(Slot* slot, TypeInfo info) {
ASSERT(slot->type() == Slot::LOCAL || slot->type() == Slot::PARAMETER);
if (slot->type() == Slot::LOCAL) {
frame_->SetTypeForLocalAt(slot->index(), info);
// the bottom check of the loop condition.
if (node->is_fast_smi_loop()) {
// Set number type of the loop variable to smi.
- SetTypeForStackSlot(node->loop_variable()->slot(), NumberInfo::Smi());
+ SetTypeForStackSlot(node->loop_variable()->slot(), TypeInfo::Smi());
}
Visit(node->body());
// expression if we are in a fast smi loop condition.
if (node->is_fast_smi_loop() && has_valid_frame()) {
// Set number type of the loop variable to smi.
- SetTypeForStackSlot(node->loop_variable()->slot(), NumberInfo::Smi());
+ SetTypeForStackSlot(node->loop_variable()->slot(), TypeInfo::Smi());
}
// Based on the condition analysis, compile the backward jump as
GenericUnaryOpStub stub(Token::SUB, overwrite);
Result operand = frame_->Pop();
Result answer = frame_->CallStub(&stub, &operand);
- answer.set_number_info(NumberInfo::Number());
+ answer.set_type_info(TypeInfo::Number());
frame_->Push(&answer);
break;
}
JumpTarget smi_label;
JumpTarget continue_label;
Result operand = frame_->Pop();
- NumberInfo operand_info = operand.number_info();
+ TypeInfo operand_info = operand.type_info();
operand.ToRegister();
if (operand_info.IsSmi()) {
if (FLAG_debug_code) __ AbortIfNotSmi(operand.reg());
__ lea(operand.reg(), Operand(operand.reg(), kSmiTagMask));
__ not_(operand.reg());
Result answer = operand;
- answer.set_number_info(NumberInfo::Smi());
+ answer.set_type_info(TypeInfo::Smi());
frame_->Push(&answer);
} else {
__ test(operand.reg(), Immediate(kSmiTagMask));
continue_label.Bind(&answer);
if (operand_info.IsInteger32()) {
- answer.set_number_info(NumberInfo::Integer32());
+ answer.set_type_info(TypeInfo::Integer32());
} else {
- answer.set_number_info(NumberInfo::Number());
+ answer.set_type_info(TypeInfo::Number());
}
frame_->Push(&answer);
}
// Smi check.
JumpTarget continue_label;
Result operand = frame_->Pop();
- NumberInfo operand_info = operand.number_info();
+ TypeInfo operand_info = operand.type_info();
operand.ToRegister();
__ test(operand.reg(), Immediate(kSmiTagMask));
continue_label.Branch(zero, &operand, taken);
continue_label.Bind(&answer);
if (operand_info.IsSmi()) {
- answer.set_number_info(NumberInfo::Smi());
+ answer.set_type_info(TypeInfo::Smi());
} else if (operand_info.IsInteger32()) {
- answer.set_number_info(NumberInfo::Integer32());
+ answer.set_type_info(TypeInfo::Integer32());
} else {
- answer.set_number_info(NumberInfo::Number());
+ answer.set_type_info(TypeInfo::Number());
}
frame_->Push(&answer);
break;
// The return value for postfix operations is the
// same as the input, and has the same number info.
- old_value.set_number_info(new_value.number_info());
+ old_value.set_type_info(new_value.type_info());
}
// Ensure the new value is writable.
// The result of ++ or -- is an Integer32 if the
// input is a smi. Otherwise it is a number.
if (new_value.is_smi()) {
- new_value.set_number_info(NumberInfo::Integer32());
+ new_value.set_type_info(TypeInfo::Integer32());
} else {
- new_value.set_number_info(NumberInfo::Number());
+ new_value.set_type_info(TypeInfo::Number());
}
// Postfix: store the old value in the allocated slot under the
unsafe_bailout_->Branch(negative);
__ bind(¬_negative_zero);
}
- Result edx_result(edx, NumberInfo::Integer32());
+ Result edx_result(edx, TypeInfo::Integer32());
edx_result.set_untagged_int32(true);
frame_->Push(&edx_result);
} else {
ASSERT(op == Token::DIV);
__ test(edx, Operand(edx));
unsafe_bailout_->Branch(not_equal);
- Result eax_result(eax, NumberInfo::Integer32());
+ Result eax_result(eax, TypeInfo::Integer32());
eax_result.set_untagged_int32(true);
frame_->Push(&eax_result);
}
static void CheckTwoForSminess(MacroAssembler* masm,
Register left, Register right, Register scratch,
- NumberInfo left_info, NumberInfo right_info,
+ TypeInfo left_info, TypeInfo right_info,
DeferredInlineBinaryOperation* deferred) {
if (left.is(right)) {
if (!left_info.IsSmi()) {
// trashed registers.
void IntegerConvert(MacroAssembler* masm,
Register source,
- NumberInfo number_info,
+ TypeInfo type_info,
bool use_sse3,
Label* conversion_failure) {
ASSERT(!source.is(ecx) && !source.is(edi) && !source.is(ebx));
Label done, right_exponent, normal_exponent;
Register scratch = ebx;
Register scratch2 = edi;
- if (!number_info.IsInteger32() || !use_sse3) {
+ if (!type_info.IsInteger32() || !use_sse3) {
// Get exponent word.
__ mov(scratch, FieldOperand(source, HeapNumber::kExponentOffset));
// Get exponent alone in scratch2.
}
if (use_sse3) {
CpuFeatures::Scope scope(SSE3);
- if (!number_info.IsInteger32()) {
+ if (!type_info.IsInteger32()) {
// Check whether the exponent is too big for a 64 bit signed integer.
static const uint32_t kTooBigExponent =
(HeapNumber::kExponentBias + 63) << HeapNumber::kExponentShift;
// Input: edx, eax are the left and right objects of a bit op.
// Output: eax, ecx are left and right integers for a bit op.
void FloatingPointHelper::LoadNumbersAsIntegers(MacroAssembler* masm,
- NumberInfo number_info,
+ TypeInfo type_info,
bool use_sse3,
Label* conversion_failure) {
// Check float operands.
Label arg2_is_object, check_undefined_arg2;
Label load_arg2, done;
- if (!number_info.IsDouble()) {
- if (!number_info.IsSmi()) {
+ if (!type_info.IsDouble()) {
+ if (!type_info.IsSmi()) {
__ test(edx, Immediate(kSmiTagMask));
__ j(not_zero, &arg1_is_object);
} else {
__ bind(&arg1_is_object);
// Get the untagged integer version of the edx heap number in ecx.
- IntegerConvert(masm, edx, number_info, use_sse3, conversion_failure);
+ IntegerConvert(masm, edx, type_info, use_sse3, conversion_failure);
__ mov(edx, ecx);
// Here edx has the untagged integer, eax has a Smi or a heap number.
__ bind(&load_arg2);
- if (!number_info.IsDouble()) {
+ if (!type_info.IsDouble()) {
// Test if arg2 is a Smi.
- if (!number_info.IsSmi()) {
+ if (!type_info.IsSmi()) {
__ test(eax, Immediate(kSmiTagMask));
__ j(not_zero, &arg2_is_object);
} else {
__ bind(&arg2_is_object);
// Get the untagged integer version of the eax heap number in ecx.
- IntegerConvert(masm, eax, number_info, use_sse3, conversion_failure);
+ IntegerConvert(masm, eax, type_info, use_sse3, conversion_failure);
__ bind(&done);
__ mov(eax, edx);
}
// Get the untagged integer version of the edx heap number in ecx.
IntegerConvert(masm,
edx,
- NumberInfo::Unknown(),
+ TypeInfo::Unknown(),
use_sse3,
conversion_failure);
__ mov(edx, ecx);
// Get the untagged integer version of the eax heap number in ecx.
IntegerConvert(masm,
eax,
- NumberInfo::Unknown(),
+ TypeInfo::Unknown(),
use_sse3,
conversion_failure);
__ bind(&done);
void FloatingPointHelper::LoadAsIntegers(MacroAssembler* masm,
- NumberInfo number_info,
+ TypeInfo type_info,
bool use_sse3,
Label* conversion_failure) {
- if (number_info.IsNumber()) {
- LoadNumbersAsIntegers(masm, number_info, use_sse3, conversion_failure);
+ if (type_info.IsNumber()) {
+ LoadNumbersAsIntegers(masm, type_info, use_sse3, conversion_failure);
} else {
LoadUnknownsAsIntegers(masm, use_sse3, conversion_failure);
}
// Convert the heap number in eax to an untagged integer in ecx.
IntegerConvert(masm,
eax,
- NumberInfo::Unknown(),
+ TypeInfo::Unknown(),
CpuFeatures::IsSupported(SSE3),
&slow);
void CodeForDoWhileConditionPosition(DoWhileStatement* stmt);
void CodeForSourcePosition(int pos);
- void SetTypeForStackSlot(Slot* slot, NumberInfo info);
+ void SetTypeForStackSlot(Slot* slot, TypeInfo info);
#ifdef DEBUG
// True if the registers are valid for entry to a block. There should
GenericBinaryOpStub(Token::Value op,
OverwriteMode mode,
GenericBinaryFlags flags,
- NumberInfo operands_type)
+ TypeInfo operands_type)
: op_(op),
mode_(mode),
flags_(flags),
args_in_registers_(ArgsInRegistersBits::decode(key)),
args_reversed_(ArgsReversedBits::decode(key)),
use_sse3_(SSE3Bits::decode(key)),
- static_operands_type_(NumberInfo::ExpandedRepresentation(
+ static_operands_type_(TypeInfo::ExpandedRepresentation(
StaticTypeInfoBits::decode(key))),
runtime_operands_type_(runtime_operands_type),
name_(NULL) {
bool use_sse3_;
// Number type information of operands, determined by code generator.
- NumberInfo static_operands_type_;
+ TypeInfo static_operands_type_;
// Operand type information determined at runtime.
BinaryOpIC::TypeInfo runtime_operands_type_;
#ifdef DEBUG
void Print() {
PrintF("GenericBinaryOpStub %d (op %s), "
- "(mode %d, flags %d, registers %d, reversed %d, number_info %s)\n",
+ "(mode %d, flags %d, registers %d, reversed %d, type_info %s)\n",
MinorKey(),
Token::String(op_),
static_cast<int>(mode_),
GenericBinaryOpStub stub(op,
NO_OVERWRITE,
NO_GENERIC_BINARY_FLAGS,
- NumberInfo::Unknown());
+ TypeInfo::Unknown());
__ CallStub(&stub);
Apply(context, eax);
}
GenericBinaryOpStub stub(expr->binary_op(),
NO_OVERWRITE,
NO_GENERIC_BINARY_FLAGS,
- NumberInfo::Unknown());
+ TypeInfo::Unknown());
stub.GenerateCall(masm(), eax, Smi::FromInt(1));
__ bind(&done);
Immediate(handle()));
}
// This result becomes a copy of the fresh one.
- fresh.set_number_info(number_info());
+ fresh.set_type_info(type_info());
*this = fresh;
}
ASSERT(is_register());
}
}
}
- fresh.set_number_info(number_info());
+ fresh.set_type_info(type_info());
fresh.set_untagged_int32(is_untagged_int32());
*this = fresh;
} else if (is_register() && reg().is(target)) {
if (element.is_constant() || element.is_copy()) {
if (element.is_synced()) {
// Just spill.
- elements_[i] = FrameElement::MemoryElement(NumberInfo::Unknown());
+ elements_[i] = FrameElement::MemoryElement(TypeInfo::Unknown());
} else {
// Allocate to a register.
FrameElement backing_element; // Invalid if not a copy.
elements_[i] =
FrameElement::RegisterElement(fresh.reg(),
FrameElement::NOT_SYNCED,
- NumberInfo::Unknown());
+ TypeInfo::Unknown());
Use(fresh.reg(), i);
// Emit a move.
// 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::Unknown());
+ elements_[i].set_type_info(TypeInfo::Unknown());
}
}
}
elements_[new_backing_index] =
FrameElement::RegisterElement(backing_reg,
FrameElement::SYNCED,
- original.number_info());
+ original.type_info());
} else {
elements_[new_backing_index] =
FrameElement::RegisterElement(backing_reg,
FrameElement::NOT_SYNCED,
- original.number_info());
+ original.type_info());
}
// Update the other copies.
for (int i = new_backing_index + 1; i < element_count(); i++) {
FrameElement new_element =
FrameElement::RegisterElement(fresh.reg(),
FrameElement::NOT_SYNCED,
- original.number_info());
+ original.type_info());
Use(fresh.reg(), element_count());
elements_.Add(new_element);
__ mov(fresh.reg(), Operand(ebp, fp_relative(index)));
FrameElement new_element =
FrameElement::RegisterElement(fresh_reg,
FrameElement::NOT_SYNCED,
- original.number_info());
+ original.type_info());
new_element.set_untagged_int32(true);
Use(fresh_reg, element_count());
fresh.Unuse(); // BreakTarget does not handle a live Result well.
__ mov(fresh_reg, Operand(ebp, fp_relative(index)));
}
// Now convert the value to int32, or bail out.
- if (original.number_info().IsSmi()) {
+ if (original.type_info().IsSmi()) {
__ SmiUntag(fresh_reg);
// Pushing the element is completely done.
} else {
__ jmp(&done);
__ bind(¬_smi);
- if (!original.number_info().IsNumber()) {
+ if (!original.type_info().IsNumber()) {
__ cmp(FieldOperand(fresh_reg, HeapObject::kMapOffset),
Factory::heap_number_map());
cgen()->unsafe_bailout_->Branch(not_equal);
ASSERT(element.is_untagged_int32() == cgen()->in_safe_int32_mode());
// Get number type information of the result.
- NumberInfo info;
+ TypeInfo info;
if (!element.is_copy()) {
- info = element.number_info();
+ info = element.type_info();
} else {
- info = elements_[element.index()].number_info();
+ info = elements_[element.index()].type_info();
}
bool pop_needed = (stack_pointer_ == index);
Result temp = cgen()->allocator()->Allocate();
ASSERT(temp.is_valid());
__ pop(temp.reg());
- temp.set_number_info(info);
+ temp.set_type_info(info);
temp.set_untagged_int32(element.is_untagged_int32());
return temp;
}
FrameElement new_element =
FrameElement::RegisterElement(temp.reg(),
FrameElement::SYNCED,
- element.number_info());
+ element.type_info());
// Preserve the copy flag on the element.
if (element.is_copied()) new_element.set_copied();
elements_[index] = new_element;
}
-void VirtualFrame::EmitPush(Register reg, NumberInfo info) {
+void VirtualFrame::EmitPush(Register reg, TypeInfo info) {
ASSERT(stack_pointer_ == element_count() - 1);
elements_.Add(FrameElement::MemoryElement(info));
stack_pointer_++;
}
-void VirtualFrame::EmitPush(Operand operand, NumberInfo info) {
+void VirtualFrame::EmitPush(Operand operand, TypeInfo info) {
ASSERT(stack_pointer_ == element_count() - 1);
elements_.Add(FrameElement::MemoryElement(info));
stack_pointer_++;
}
-void VirtualFrame::EmitPush(Immediate immediate, NumberInfo info) {
+void VirtualFrame::EmitPush(Immediate immediate, TypeInfo info) {
ASSERT(stack_pointer_ == element_count() - 1);
elements_.Add(FrameElement::MemoryElement(info));
stack_pointer_++;
#ifndef V8_IA32_VIRTUAL_FRAME_IA32_H_
#define V8_IA32_VIRTUAL_FRAME_IA32_H_
-#include "number-info.h"
+#include "type-info.h"
#include "register-allocator.h"
#include "scopes.h"
// Create a duplicate of an existing valid frame element.
FrameElement CopyElementAt(int index,
- NumberInfo info = NumberInfo::Uninitialized());
+ TypeInfo info = TypeInfo::Uninitialized());
// The number of elements on the virtual frame.
int element_count() { return elements_.length(); }
// Push an element on top of the expression stack and emit a
// corresponding push instruction.
void EmitPush(Register reg,
- NumberInfo info = NumberInfo::Unknown());
+ TypeInfo info = TypeInfo::Unknown());
void EmitPush(Operand operand,
- NumberInfo info = NumberInfo::Unknown());
+ TypeInfo info = TypeInfo::Unknown());
void EmitPush(Immediate immediate,
- NumberInfo info = NumberInfo::Unknown());
+ TypeInfo info = TypeInfo::Unknown());
// Push an element on the virtual frame.
- inline void Push(Register reg, NumberInfo info = NumberInfo::Unknown());
+ inline void Push(Register reg, TypeInfo info = TypeInfo::Unknown());
inline void Push(Handle<Object> value);
inline void Push(Smi* value);
// This assert will trigger if you try to push the same value twice.
ASSERT(result->is_valid());
if (result->is_register()) {
- Push(result->reg(), result->number_info());
+ Push(result->reg(), result->type_info());
} else {
ASSERT(result->is_constant());
Push(result->handle());
}
// Update the type information of a variable frame element directly.
- inline void SetTypeForLocalAt(int index, NumberInfo info);
- inline void SetTypeForParamAt(int index, NumberInfo info);
+ inline void SetTypeForLocalAt(int index, TypeInfo info);
+ inline void SetTypeForParamAt(int index, TypeInfo info);
private:
static const int kLocal0Offset = JavaScriptFrameConstants::kLocal0Offset;
entry_frame_->elements_[target->index()].set_copied();
}
if (direction_ == BIDIRECTIONAL && !target->is_copy()) {
- element->set_number_info(NumberInfo::Unknown());
+ element->set_type_info(TypeInfo::Unknown());
}
}
// We overwrite the number information of one of the incoming frames.
// This is safe because we only use the frame for emitting merge code.
// The number information of incoming frames is not used anymore.
- element->set_number_info(NumberInfo::Combine(element->number_info(),
- other->number_info()));
+ element->set_type_info(TypeInfo::Combine(element->type_info(),
+ other->type_info()));
}
}
elements[i] = element;
FrameElement* target = elements[index];
if (target == NULL) {
entry_frame_->elements_.Add(
- FrameElement::MemoryElement(NumberInfo::Uninitialized()));
+ FrameElement::MemoryElement(TypeInfo::Uninitialized()));
} else {
entry_frame_->elements_.Add(*target);
InitializeEntryElement(index, target);
RegisterFile candidate_registers;
int best_count = kMinInt;
int best_reg_num = RegisterAllocator::kInvalidRegister;
- NumberInfo info = NumberInfo::Uninitialized();
+ TypeInfo info = TypeInfo::Uninitialized();
for (int j = 0; j < reaching_frames_.length(); j++) {
FrameElement element = reaching_frames_[j]->elements_[i];
if (direction_ == BIDIRECTIONAL) {
- info = NumberInfo::Unknown();
+ info = TypeInfo::Unknown();
} else if (!element.is_copy()) {
- info = NumberInfo::Combine(info, element.number_info());
+ info = TypeInfo::Combine(info, element.type_info());
} else {
// New elements will not be copies, so get number information from
// backing element in the reaching frame.
- info = NumberInfo::Combine(info,
- reaching_frames_[j]->elements_[element.index()].number_info());
+ info = TypeInfo::Combine(info,
+ reaching_frames_[j]->elements_[element.index()].type_info());
}
is_synced = is_synced && element.is_synced();
if (element.is_register() && !entry_frame_->is_used(element.reg())) {
if (is_synced) {
// Already recorded as a memory element.
// Set combined number info.
- entry_frame_->elements_[i].set_number_info(info);
+ entry_frame_->elements_[i].set_type_info(info);
continue;
}
Register reg = RegisterAllocator::ToRegister(best_reg_num);
entry_frame_->elements_[i] =
FrameElement::RegisterElement(reg, FrameElement::NOT_SYNCED,
- NumberInfo::Uninitialized());
+ TypeInfo::Uninitialized());
if (is_copied) entry_frame_->elements_[i].set_copied();
entry_frame_->set_register_location(reg, i);
}
// Set combined number info.
- entry_frame_->elements_[i].set_number_info(info);
+ entry_frame_->elements_[i].set_type_info(info);
}
}
if (direction_ == BIDIRECTIONAL) {
for (int i = 0; i < length; ++i) {
if (!entry_frame_->elements_[i].is_copy()) {
- ASSERT(entry_frame_->elements_[i].number_info().IsUnknown());
+ ASSERT(entry_frame_->elements_[i].type_info().IsUnknown());
}
}
}
+++ /dev/null
-// Copyright 2010 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-#ifndef V8_NUMBER_INFO_INL_H_
-#define V8_NUMBER_INFO_INL_H_
-
-#include "number-info.h"
-#include "objects-inl.h"
-
-namespace v8 {
-namespace internal {
-
-
-NumberInfo NumberInfo::TypeFromValue(Handle<Object> value) {
- NumberInfo info;
- if (value->IsSmi()) {
- info = NumberInfo::Smi();
- } else if (value->IsHeapNumber()) {
- info = NumberInfo::IsInt32Double(HeapNumber::cast(*value)->value())
- ? NumberInfo::Integer32()
- : NumberInfo::Double();
- } else {
- info = NumberInfo::Unknown();
- }
- return info;
-}
-
-
-} } // namespace v8::internal
-
-#endif // V8_NUMBER_INFO_INL_H_
+++ /dev/null
-// Copyright 2010 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-#ifndef V8_NUMBER_INFO_H_
-#define V8_NUMBER_INFO_H_
-
-#include "globals.h"
-
-namespace v8 {
-namespace internal {
-
-// Unknown
-// |
-// PrimitiveType
-// | \--------|
-// Number String
-// / | |
-// Double Integer32 |
-// | | /
-// | Smi /
-// | / /
-// Uninitialized.
-
-class NumberInfo {
- public:
- NumberInfo() { }
-
- static inline NumberInfo Unknown();
- // We know it's a primitive type.
- static inline NumberInfo Primitive();
- // 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 Double();
- // We know it's a string.
- static inline NumberInfo String();
- // We haven't started collecting info yet.
- static inline NumberInfo Uninitialized();
-
- // Return compact representation. Very sensitive to enum values below!
- // Compacting drops information about primtive types and strings types.
- // We use the compact representation when we only care about number types.
- int ThreeBitRepresentation() {
- ASSERT(type_ != kUninitializedType);
- int answer = type_ & 0xf;
- answer = answer > 6 ? answer - 2 : answer;
- 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);
- t = (t == kUnknownType) ? t : static_cast<Type>(t | kPrimitiveType);
- ASSERT(t == kUnknownType ||
- t == kNumberType ||
- t == kInteger32Type ||
- t == kSmiType ||
- t == kDoubleType);
- return NumberInfo(t);
- }
-
- int ToInt() {
- return type_;
- }
-
- static NumberInfo FromInt(int bit_representation) {
- Type t = static_cast<Type>(bit_representation);
- ASSERT(t == kUnknownType ||
- t == kPrimitiveType ||
- t == kNumberType ||
- t == kInteger32Type ||
- t == kSmiType ||
- t == kDoubleType ||
- t == kStringType);
- return NumberInfo(t);
- }
-
- // Return the weakest (least precise) common type.
- static NumberInfo Combine(NumberInfo a, NumberInfo b) {
- return NumberInfo(static_cast<Type>(a.type_ & b.type_));
- }
-
-
- // Integer32 is an integer that can be represented as either a signed
- // 32-bit integer or as an unsigned 32-bit integer. It has to be
- // in the range [-2^31, 2^32 - 1]. We also have to check for negative 0
- // as it is not an Integer32.
- static inline bool IsInt32Double(double value) {
- const DoubleRepresentation minus_zero(-0.0);
- DoubleRepresentation rep(value);
- if (rep.bits == minus_zero.bits) return false;
- if (value >= kMinInt && value <= kMaxUInt32) {
- if (value <= kMaxInt && value == static_cast<int32_t>(value)) {
- return true;
- }
- if (value == static_cast<uint32_t>(value)) return true;
- }
- return false;
- }
-
- static inline NumberInfo TypeFromValue(Handle<Object> value);
-
- inline bool IsUnknown() {
- return type_ == kUnknownType;
- }
-
- 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 IsDouble() {
- ASSERT(type_ != kUninitializedType);
- return ((type_ & kDoubleType) == kDoubleType);
- }
-
- inline bool IsUninitialized() {
- return type_ == kUninitializedType;
- }
-
- const char* ToString() {
- switch (type_) {
- case kUnknownType: return "UnknownType";
- case kPrimitiveType: return "PrimitiveType";
- case kNumberType: return "NumberType";
- case kInteger32Type: return "Integer32Type";
- case kSmiType: return "SmiType";
- case kDoubleType: return "DoubleType";
- case kStringType: return "StringType";
- case kUninitializedType:
- UNREACHABLE();
- return "UninitializedType";
- }
- UNREACHABLE();
- return "Unreachable code";
- }
-
- private:
- // We use 6 bits to represent the types.
- enum Type {
- kUnknownType = 0, // 000000
- kPrimitiveType = 0x10, // 010000
- kNumberType = 0x11, // 010001
- kInteger32Type = 0x13, // 010011
- kSmiType = 0x17, // 010111
- kDoubleType = 0x19, // 011001
- kStringType = 0x30, // 110000
- kUninitializedType = 0x3f // 111111
- };
- explicit inline NumberInfo(Type t) : type_(t) { }
-
- Type type_;
-};
-
-
-NumberInfo NumberInfo::Unknown() {
- return NumberInfo(kUnknownType);
-}
-
-
-NumberInfo NumberInfo::Primitive() {
- return NumberInfo(kPrimitiveType);
-}
-
-
-NumberInfo NumberInfo::Number() {
- return NumberInfo(kNumberType);
-}
-
-
-NumberInfo NumberInfo::Integer32() {
- return NumberInfo(kInteger32Type);
-}
-
-
-NumberInfo NumberInfo::Smi() {
- return NumberInfo(kSmiType);
-}
-
-
-NumberInfo NumberInfo::Double() {
- return NumberInfo(kDoubleType);
-}
-
-
-NumberInfo NumberInfo::String() {
- return NumberInfo(kStringType);
-}
-
-
-NumberInfo NumberInfo::Uninitialized() {
- return NumberInfo(kUninitializedType);
-}
-
-} } // namespace v8::internal
-
-#endif // V8_NUMBER_INFO_H_
}
-NumberInfo Result::number_info() const {
+TypeInfo Result::type_info() const {
ASSERT(is_valid());
- return NumberInfo::FromInt(NumberInfoField::decode(value_));
+ return TypeInfo::FromInt(TypeInfoField::decode(value_));
}
-void Result::set_number_info(NumberInfo info) {
+void Result::set_type_info(TypeInfo info) {
ASSERT(is_valid());
- value_ &= ~NumberInfoField::mask();
- value_ |= NumberInfoField::encode(info.ToInt());
+ value_ &= ~TypeInfoField::mask();
+ value_ |= TypeInfoField::encode(info.ToInt());
}
bool Result::is_number() const {
- return number_info().IsNumber();
+ return type_info().IsNumber();
}
bool Result::is_smi() const {
- return number_info().IsSmi();
+ return type_info().IsSmi();
}
bool Result::is_integer32() const {
- return number_info().IsInteger32();
+ return type_info().IsInteger32();
}
bool Result::is_double() const {
- return number_info().IsDouble();
+ return type_info().IsDouble();
}
} } // namespace v8::internal
// Result implementation.
-Result::Result(Register reg, NumberInfo info) {
+Result::Result(Register reg, TypeInfo info) {
ASSERT(reg.is_valid() && !RegisterAllocator::IsReserved(reg));
CodeGeneratorScope::Current()->allocator()->Use(reg);
value_ = TypeField::encode(REGISTER)
- | NumberInfoField::encode(info.ToInt())
+ | TypeInfoField::encode(info.ToInt())
| DataField::encode(reg.code_);
}
#define V8_REGISTER_ALLOCATOR_H_
#include "macro-assembler.h"
-#include "number-info-inl.h"
+#include "type-info-inl.h"
#if V8_TARGET_ARCH_IA32
#include "ia32/register-allocator-ia32.h"
Result() { invalidate(); }
// Construct a register Result.
- explicit Result(Register reg, NumberInfo info = NumberInfo::Unknown());
+ explicit Result(Register reg, TypeInfo info = TypeInfo::Unknown());
// Construct a Result whose value is a compile-time constant.
explicit Result(Handle<Object> value) {
- NumberInfo info = NumberInfo::TypeFromValue(value);
+ TypeInfo info = TypeInfo::TypeFromValue(value);
value_ = TypeField::encode(CONSTANT)
- | NumberInfoField::encode(info.ToInt())
+ | TypeInfoField::encode(info.ToInt())
| IsUntaggedInt32Field::encode(false)
| DataField::encode(ConstantList()->length());
ConstantList()->Add(value);
void invalidate() { value_ = TypeField::encode(INVALID); }
- inline NumberInfo number_info() const;
- inline void set_number_info(NumberInfo info);
+ inline TypeInfo type_info() const;
+ inline void set_type_info(TypeInfo info);
inline bool is_number() const;
inline bool is_smi() const;
inline bool is_integer32() const;
// Declare BitFields with template parameters <type, start, size>.
class TypeField: public BitField<Type, 0, 2> {};
- class NumberInfoField : public BitField<int, 2, 6> {};
+ class TypeInfoField : public BitField<int, 2, 6> {};
class IsUntaggedInt32Field : public BitField<bool, 8, 1> {};
class DataField: public BitField<uint32_t, 9, 32 - 9> {};
--- /dev/null
+// Copyright 2010 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following
+// disclaimer in the documentation and/or other materials provided
+// with the distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#ifndef V8_TYPE_INFO_INL_H_
+#define V8_TYPE_INFO_INL_H_
+
+#include "type-info.h"
+#include "objects-inl.h"
+
+namespace v8 {
+namespace internal {
+
+
+TypeInfo TypeInfo::TypeFromValue(Handle<Object> value) {
+ TypeInfo info;
+ if (value->IsSmi()) {
+ info = TypeInfo::Smi();
+ } else if (value->IsHeapNumber()) {
+ info = TypeInfo::IsInt32Double(HeapNumber::cast(*value)->value())
+ ? TypeInfo::Integer32()
+ : TypeInfo::Double();
+ } else {
+ info = TypeInfo::Unknown();
+ }
+ return info;
+}
+
+
+} } // namespace v8::internal
+
+#endif // V8_TYPE_INFO_INL_H_
--- /dev/null
+// Copyright 2010 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following
+// disclaimer in the documentation and/or other materials provided
+// with the distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#ifndef V8_TYPE_INFO_H_
+#define V8_TYPE_INFO_H_
+
+#include "globals.h"
+
+namespace v8 {
+namespace internal {
+
+// Unknown
+// |
+// PrimitiveType
+// | \--------|
+// Number String
+// / | |
+// Double Integer32 |
+// | | /
+// | Smi /
+// | / /
+// Uninitialized.
+
+class TypeInfo {
+ public:
+ TypeInfo() { }
+
+ static inline TypeInfo Unknown();
+ // We know it's a primitive type.
+ static inline TypeInfo Primitive();
+ // We know it's a number of some sort.
+ static inline TypeInfo Number();
+ // We know it's signed or unsigned 32 bit integer.
+ static inline TypeInfo Integer32();
+ // We know it's a Smi.
+ static inline TypeInfo Smi();
+ // We know it's a heap number.
+ static inline TypeInfo Double();
+ // We know it's a string.
+ static inline TypeInfo String();
+ // We haven't started collecting info yet.
+ static inline TypeInfo Uninitialized();
+
+ // Return compact representation. Very sensitive to enum values below!
+ // Compacting drops information about primtive types and strings types.
+ // We use the compact representation when we only care about number types.
+ int ThreeBitRepresentation() {
+ ASSERT(type_ != kUninitializedType);
+ int answer = type_ & 0xf;
+ answer = answer > 6 ? answer - 2 : answer;
+ ASSERT(answer >= 0);
+ ASSERT(answer <= 7);
+ return answer;
+ }
+
+ // Decode compact representation. Very sensitive to enum values below!
+ static TypeInfo ExpandedRepresentation(int three_bit_representation) {
+ Type t = static_cast<Type>(three_bit_representation >= 6 ?
+ three_bit_representation + 2 :
+ three_bit_representation);
+ t = (t == kUnknownType) ? t : static_cast<Type>(t | kPrimitiveType);
+ ASSERT(t == kUnknownType ||
+ t == kNumberType ||
+ t == kInteger32Type ||
+ t == kSmiType ||
+ t == kDoubleType);
+ return TypeInfo(t);
+ }
+
+ int ToInt() {
+ return type_;
+ }
+
+ static TypeInfo FromInt(int bit_representation) {
+ Type t = static_cast<Type>(bit_representation);
+ ASSERT(t == kUnknownType ||
+ t == kPrimitiveType ||
+ t == kNumberType ||
+ t == kInteger32Type ||
+ t == kSmiType ||
+ t == kDoubleType ||
+ t == kStringType);
+ return TypeInfo(t);
+ }
+
+ // Return the weakest (least precise) common type.
+ static TypeInfo Combine(TypeInfo a, TypeInfo b) {
+ return TypeInfo(static_cast<Type>(a.type_ & b.type_));
+ }
+
+
+ // Integer32 is an integer that can be represented as either a signed
+ // 32-bit integer or as an unsigned 32-bit integer. It has to be
+ // in the range [-2^31, 2^32 - 1]. We also have to check for negative 0
+ // as it is not an Integer32.
+ static inline bool IsInt32Double(double value) {
+ const DoubleRepresentation minus_zero(-0.0);
+ DoubleRepresentation rep(value);
+ if (rep.bits == minus_zero.bits) return false;
+ if (value >= kMinInt && value <= kMaxUInt32) {
+ if (value <= kMaxInt && value == static_cast<int32_t>(value)) {
+ return true;
+ }
+ if (value == static_cast<uint32_t>(value)) return true;
+ }
+ return false;
+ }
+
+ static inline TypeInfo TypeFromValue(Handle<Object> value);
+
+ inline bool IsUnknown() {
+ return type_ == kUnknownType;
+ }
+
+ 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 IsDouble() {
+ ASSERT(type_ != kUninitializedType);
+ return ((type_ & kDoubleType) == kDoubleType);
+ }
+
+ inline bool IsUninitialized() {
+ return type_ == kUninitializedType;
+ }
+
+ const char* ToString() {
+ switch (type_) {
+ case kUnknownType: return "UnknownType";
+ case kPrimitiveType: return "PrimitiveType";
+ case kNumberType: return "NumberType";
+ case kInteger32Type: return "Integer32Type";
+ case kSmiType: return "SmiType";
+ case kDoubleType: return "DoubleType";
+ case kStringType: return "StringType";
+ case kUninitializedType:
+ UNREACHABLE();
+ return "UninitializedType";
+ }
+ UNREACHABLE();
+ return "Unreachable code";
+ }
+
+ private:
+ // We use 6 bits to represent the types.
+ enum Type {
+ kUnknownType = 0, // 000000
+ kPrimitiveType = 0x10, // 010000
+ kNumberType = 0x11, // 010001
+ kInteger32Type = 0x13, // 010011
+ kSmiType = 0x17, // 010111
+ kDoubleType = 0x19, // 011001
+ kStringType = 0x30, // 110000
+ kUninitializedType = 0x3f // 111111
+ };
+ explicit inline TypeInfo(Type t) : type_(t) { }
+
+ Type type_;
+};
+
+
+TypeInfo TypeInfo::Unknown() {
+ return TypeInfo(kUnknownType);
+}
+
+
+TypeInfo TypeInfo::Primitive() {
+ return TypeInfo(kPrimitiveType);
+}
+
+
+TypeInfo TypeInfo::Number() {
+ return TypeInfo(kNumberType);
+}
+
+
+TypeInfo TypeInfo::Integer32() {
+ return TypeInfo(kInteger32Type);
+}
+
+
+TypeInfo TypeInfo::Smi() {
+ return TypeInfo(kSmiType);
+}
+
+
+TypeInfo TypeInfo::Double() {
+ return TypeInfo(kDoubleType);
+}
+
+
+TypeInfo TypeInfo::String() {
+ return TypeInfo(kStringType);
+}
+
+
+TypeInfo TypeInfo::Uninitialized() {
+ return TypeInfo(kUninitializedType);
+}
+
+} } // namespace v8::internal
+
+#endif // V8_TYPE_INFO_H_
: 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::Unknown()));
+ elements_.Add(FrameElement::MemoryElement(TypeInfo::Unknown()));
}
for (int i = 0; i < RegisterAllocator::kNumRegisters; i++) {
register_locations_[i] = kIllegalIndex;
}
-void VirtualFrame::Push(Register reg, NumberInfo info) {
+void VirtualFrame::Push(Register reg, TypeInfo info) {
if (is_used(reg)) {
int index = register_location(reg);
FrameElement element = CopyElementAt(index, info);
}
-void VirtualFrame::SetTypeForLocalAt(int index, NumberInfo info) {
- elements_[local0_index() + index].set_number_info(info);
+void VirtualFrame::SetTypeForLocalAt(int index, TypeInfo info) {
+ elements_[local0_index() + index].set_type_info(info);
}
-void VirtualFrame::SetTypeForParamAt(int index, NumberInfo info) {
- elements_[param0_index() + index].set_number_info(info);
+void VirtualFrame::SetTypeForParamAt(int index, TypeInfo info) {
+ elements_[param0_index() + index].set_type_info(info);
}
// 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 info) {
+FrameElement VirtualFrame::CopyElementAt(int index, TypeInfo info) {
ASSERT(index >= 0);
ASSERT(index < element_count());
result.set_index(index);
elements_[index].set_copied();
// Update backing element's number information.
- NumberInfo existing = elements_[index].number_info();
+ TypeInfo existing = elements_[index].type_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.ToInt() & existing.ToInt()) == existing.ToInt());
ASSERT((info.ToInt() | existing.ToInt()) == info.ToInt());
- elements_[index].set_number_info(!info.IsUninitialized()
+ elements_[index].set_type_info(!info.IsUninitialized()
? info
: existing);
break;
ASSERT(stack_pointer_ == element_count() - 1);
for (int i = 0; i < count; i++) {
- elements_.Add(FrameElement::MemoryElement(NumberInfo::Unknown()));
+ elements_.Add(FrameElement::MemoryElement(TypeInfo::Unknown()));
}
stack_pointer_ += count;
}
SyncElementAt(index);
// Number type information is preserved.
// Copies get their number information from their backing element.
- NumberInfo info;
+ TypeInfo info;
if (!elements_[index].is_copy()) {
- info = elements_[index].number_info();
+ info = elements_[index].type_info();
} else {
- info = elements_[elements_[index].index()].number_info();
+ info = elements_[elements_[index].index()].type_info();
}
// The element is now in memory. Its copied flag is preserved.
FrameElement new_element = FrameElement::MemoryElement(info);
elements_[frame_index] =
FrameElement::RegisterElement(value->reg(),
FrameElement::NOT_SYNCED,
- value->number_info());
+ value->type_info());
}
} else {
ASSERT(value->is_constant());
if (value.is_number()) {
Comment cmnt(masm_, "ONLY_NUMBER");
- // Fast case if NumberInfo indicates only numbers.
+ // Fast case if TypeInfo indicates only numbers.
if (FLAG_debug_code) {
__ AbortIfNotNumber(value.reg(), "ToBoolean operand is not a number.");
}
}
// Get number type of left and right sub-expressions.
- NumberInfo operands_type =
- NumberInfo::Combine(left.number_info(), right.number_info());
+ TypeInfo operands_type =
+ TypeInfo::Combine(left.type_info(), right.type_info());
Result answer;
if (left_is_non_smi_constant || right_is_non_smi_constant) {
}
}
- // Set NumberInfo of result according to the operation performed.
+ // Set TypeInfo 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 result_type = NumberInfo::Unknown();
+ TypeInfo result_type = TypeInfo::Unknown();
switch (op) {
case Token::COMMA:
- result_type = right.number_info();
+ result_type = right.type_info();
break;
case Token::OR:
case Token::AND:
case Token::BIT_XOR:
case Token::BIT_AND:
// Result is always a smi.
- result_type = NumberInfo::Smi();
+ result_type = TypeInfo::Smi();
break;
case Token::SAR:
case Token::SHL:
// Result is always a smi.
- result_type = NumberInfo::Smi();
+ result_type = TypeInfo::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::Smi()
- : NumberInfo::Number();
+ ? TypeInfo::Smi()
+ : TypeInfo::Number();
break;
case Token::ADD:
// Result could be a string or a number. Check types of inputs.
result_type = operands_type.IsNumber()
- ? NumberInfo::Number()
- : NumberInfo::Unknown();
+ ? TypeInfo::Number()
+ : TypeInfo::Unknown();
break;
case Token::SUB:
case Token::MUL:
case Token::DIV:
case Token::MOD:
// Result is always a number.
- result_type = NumberInfo::Number();
+ result_type = TypeInfo::Number();
break;
default:
UNREACHABLE();
}
- answer.set_number_info(result_type);
+ answer.set_type_info(result_type);
frame_->Push(&answer);
}
GenericBinaryOpStub(Token::Value op,
OverwriteMode mode,
GenericBinaryFlags flags,
- NumberInfo operands_type = NumberInfo::Unknown())
+ TypeInfo operands_type = TypeInfo::Unknown())
: op_(op),
mode_(mode),
flags_(flags),
args_in_registers_(ArgsInRegistersBits::decode(key)),
args_reversed_(ArgsReversedBits::decode(key)),
use_sse3_(SSE3Bits::decode(key)),
- static_operands_type_(NumberInfo::ExpandedRepresentation(
+ static_operands_type_(TypeInfo::ExpandedRepresentation(
StaticTypeInfoBits::decode(key))),
runtime_operands_type_(type_info),
name_(NULL) {
bool use_sse3_;
// Number type information of operands, determined by code generator.
- NumberInfo static_operands_type_;
+ TypeInfo static_operands_type_;
// Operand type information determined at runtime.
BinaryOpIC::TypeInfo runtime_operands_type_;
ASSERT(fresh.is_valid());
CodeGeneratorScope::Current()->masm()->Move(fresh.reg(), handle());
// This result becomes a copy of the fresh one.
- fresh.set_number_info(number_info());
+ fresh.set_type_info(type_info());
*this = fresh;
}
ASSERT(is_register());
ASSERT(is_constant());
CodeGeneratorScope::Current()->masm()->Move(fresh.reg(), handle());
}
- fresh.set_number_info(number_info());
+ fresh.set_type_info(type_info());
*this = fresh;
} else if (is_register() && reg().is(target)) {
ASSERT(CodeGeneratorScope::Current()->has_valid_frame());
}
-void VirtualFrame::EmitPush(Register reg, NumberInfo info) {
+void VirtualFrame::EmitPush(Register reg, TypeInfo info) {
ASSERT(stack_pointer_ == element_count() - 1);
elements_.Add(FrameElement::MemoryElement(info));
stack_pointer_++;
}
-void VirtualFrame::EmitPush(const Operand& operand, NumberInfo info) {
+void VirtualFrame::EmitPush(const Operand& operand, TypeInfo info) {
ASSERT(stack_pointer_ == element_count() - 1);
elements_.Add(FrameElement::MemoryElement(info));
stack_pointer_++;
}
-void VirtualFrame::EmitPush(Immediate immediate, NumberInfo info) {
+void VirtualFrame::EmitPush(Immediate immediate, TypeInfo info) {
ASSERT(stack_pointer_ == element_count() - 1);
elements_.Add(FrameElement::MemoryElement(info));
stack_pointer_++;
void VirtualFrame::EmitPush(Smi* smi_value) {
ASSERT(stack_pointer_ == element_count() - 1);
- elements_.Add(FrameElement::MemoryElement(NumberInfo::Smi()));
+ elements_.Add(FrameElement::MemoryElement(TypeInfo::Smi()));
stack_pointer_++;
__ Push(smi_value);
}
void VirtualFrame::EmitPush(Handle<Object> value) {
ASSERT(stack_pointer_ == element_count() - 1);
- NumberInfo info = NumberInfo::TypeFromValue(value);
+ TypeInfo info = TypeInfo::TypeFromValue(value);
elements_.Add(FrameElement::MemoryElement(info));
stack_pointer_++;
__ Push(value);
}
-void VirtualFrame::EmitPush(Heap::RootListIndex index, NumberInfo info) {
+void VirtualFrame::EmitPush(Heap::RootListIndex index, TypeInfo info) {
ASSERT(stack_pointer_ == element_count() - 1);
elements_.Add(FrameElement::MemoryElement(info));
stack_pointer_++;
elements_[new_backing_index] =
FrameElement::RegisterElement(backing_reg,
FrameElement::SYNCED,
- original.number_info());
+ original.type_info());
} else {
elements_[new_backing_index] =
FrameElement::RegisterElement(backing_reg,
FrameElement::NOT_SYNCED,
- original.number_info());
+ original.type_info());
}
// Update the other copies.
for (int i = new_backing_index + 1; i < element_count(); i++) {
FrameElement new_element =
FrameElement::RegisterElement(fresh.reg(),
FrameElement::NOT_SYNCED,
- original.number_info());
+ original.type_info());
Use(fresh.reg(), element_count());
elements_.Add(new_element);
__ movq(fresh.reg(), Operand(rbp, fp_relative(index)));
if (element.is_constant() || element.is_copy()) {
if (element.is_synced()) {
// Just spill.
- elements_[i] = FrameElement::MemoryElement(NumberInfo::Unknown());
+ elements_[i] = FrameElement::MemoryElement(TypeInfo::Unknown());
} else {
// Allocate to a register.
FrameElement backing_element; // Invalid if not a copy.
elements_[i] =
FrameElement::RegisterElement(fresh.reg(),
FrameElement::NOT_SYNCED,
- NumberInfo::Unknown());
+ TypeInfo::Unknown());
Use(fresh.reg(), i);
// Emit a move.
// 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::Unknown());
+ elements_[i].set_type_info(TypeInfo::Unknown());
}
}
}
ASSERT(element.is_valid());
// Get number type information of the result.
- NumberInfo info;
+ TypeInfo info;
if (!element.is_copy()) {
- info = element.number_info();
+ info = element.type_info();
} else {
- info = elements_[element.index()].number_info();
+ info = elements_[element.index()].type_info();
}
bool pop_needed = (stack_pointer_ == index);
Result temp = cgen()->allocator()->Allocate();
ASSERT(temp.is_valid());
__ pop(temp.reg());
- temp.set_number_info(info);
+ temp.set_type_info(info);
return temp;
}
FrameElement new_element =
FrameElement::RegisterElement(temp.reg(),
FrameElement::SYNCED,
- element.number_info());
+ element.type_info());
// Preserve the copy flag on the element.
if (element.is_copied()) new_element.set_copied();
elements_[index] = new_element;
#ifndef V8_X64_VIRTUAL_FRAME_X64_H_
#define V8_X64_VIRTUAL_FRAME_X64_H_
-#include "number-info.h"
+#include "type-info.h"
#include "register-allocator.h"
#include "scopes.h"
// Create a duplicate of an existing valid frame element.
FrameElement CopyElementAt(int index,
- NumberInfo info = NumberInfo::Uninitialized());
+ TypeInfo info = TypeInfo::Uninitialized());
// The number of elements on the virtual frame.
int element_count() { return elements_.length(); }
// Push an element on top of the expression stack and emit a
// corresponding push instruction.
void EmitPush(Register reg,
- NumberInfo info = NumberInfo::Unknown());
+ TypeInfo info = TypeInfo::Unknown());
void EmitPush(const Operand& operand,
- NumberInfo info = NumberInfo::Unknown());
+ TypeInfo info = TypeInfo::Unknown());
void EmitPush(Heap::RootListIndex index,
- NumberInfo info = NumberInfo::Unknown());
+ TypeInfo info = TypeInfo::Unknown());
void EmitPush(Immediate immediate,
- NumberInfo info = NumberInfo::Unknown());
+ TypeInfo info = TypeInfo::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 info = NumberInfo::Unknown());
+ inline void Push(Register reg, TypeInfo info = TypeInfo::Unknown());
inline void Push(Handle<Object> value);
inline void Push(Smi* value);
// frame).
void Push(Result* result) {
if (result->is_register()) {
- Push(result->reg(), result->number_info());
+ Push(result->reg(), result->type_info());
} else {
ASSERT(result->is_constant());
Push(result->handle());
// the frame. Nip(k) is equivalent to x = Pop(), Drop(k), Push(x).
inline void Nip(int num_dropped);
- inline void SetTypeForLocalAt(int index, NumberInfo info);
- inline void SetTypeForParamAt(int index, NumberInfo info);
+ inline void SetTypeForLocalAt(int index, TypeInfo info);
+ inline void SetTypeForParamAt(int index, TypeInfo info);
private:
static const int kLocal0Offset = JavaScriptFrameConstants::kLocal0Offset;
'../../src/messages.cc',
'../../src/messages.h',
'../../src/natives.h',
- '../../src/number-info-inl.h',
- '../../src/number-info.h',
'../../src/objects-debug.cc',
'../../src/objects-inl.h',
'../../src/objects.cc',
'../../src/token.h',
'../../src/top.cc',
'../../src/top.h',
+ '../../src/type-info-inl.h',
+ '../../src/type-info.h',
'../../src/unicode-inl.h',
'../../src/unicode.cc',
'../../src/unicode.h',
RelativePath="..\..\src\natives.h"
>
</File>
- <File
- RelativePath="..\..\src\number-info-inl.h"
- >
- </File>
- <File
- RelativePath="..\..\src\number-info.h"
- >
- </File>
<File
RelativePath="..\..\src\objects-debug.cc"
>
RelativePath="..\..\src\top.h"
>
</File>
+ <File
+ RelativePath="..\..\src\type-info-inl.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\src\type-info.h"
+ >
+ </File>
<File
RelativePath="..\..\src\unicode-inl.h"
>
RelativePath="..\..\src\natives.h"
>
</File>
- <File
- RelativePath="..\..\src\number-info-inl.h"
- >
- </File>
- <File
- RelativePath="..\..\src\number-info.h"
- >
- </File>
<File
RelativePath="..\..\src\objects-debug.cc"
>
RelativePath="..\..\src\top.h"
>
</File>
+ <File
+ RelativePath="..\..\src\type-info-inl.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\src\type-info.h"
+ >
+ </File>
<File
RelativePath="..\..\src\unicode-inl.h"
>
RelativePath="..\..\src\natives.h"
>
</File>
- <File
- RelativePath="..\..\src\number-info-inl.h"
- >
- </File>
- <File
- RelativePath="..\..\src\number-info.h"
- >
- </File>
<File
RelativePath="..\..\src\objects-debug.cc"
>
RelativePath="..\..\src\top.h"
>
</File>
+ <File
+ RelativePath="..\..\src\type-info-inl.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\src\type-info.h"
+ >
+ </File>
<File
RelativePath="..\..\src\unicode-inl.h"
>