Migrate BinaryOpICs and UnaryOpICs to new type rep
R=rossberg@chromium.org Review URL: https://codereview.chromium.org/16957004 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@15172 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
parent
60c2218ae3
commit
47ba2b2dd8
@ -663,12 +663,13 @@ void ObjectLiteral::Property::RecordTypeFeedback(TypeFeedbackOracle* oracle) {
|
|||||||
|
|
||||||
|
|
||||||
void UnaryOperation::RecordTypeFeedback(TypeFeedbackOracle* oracle) {
|
void UnaryOperation::RecordTypeFeedback(TypeFeedbackOracle* oracle) {
|
||||||
type_ = oracle->UnaryType(this);
|
type_ = oracle->UnaryType(UnaryOperationFeedbackId());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void BinaryOperation::RecordTypeFeedback(TypeFeedbackOracle* oracle) {
|
void BinaryOperation::RecordTypeFeedback(TypeFeedbackOracle* oracle) {
|
||||||
oracle->BinaryType(this, &left_type_, &right_type_, &result_type_,
|
oracle->BinaryType(BinaryOperationFeedbackId(),
|
||||||
|
&left_type_, &right_type_, &result_type_,
|
||||||
&has_fixed_right_arg_, &fixed_right_arg_value_);
|
&has_fixed_right_arg_, &fixed_right_arg_value_);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
16
src/ast.h
16
src/ast.h
@ -1837,7 +1837,7 @@ class UnaryOperation: public Expression {
|
|||||||
|
|
||||||
TypeFeedbackId UnaryOperationFeedbackId() const { return reuse(id()); }
|
TypeFeedbackId UnaryOperationFeedbackId() const { return reuse(id()); }
|
||||||
void RecordTypeFeedback(TypeFeedbackOracle* oracle);
|
void RecordTypeFeedback(TypeFeedbackOracle* oracle);
|
||||||
TypeInfo type() const { return type_; }
|
Handle<Type> type() const { return type_; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
UnaryOperation(Isolate* isolate,
|
UnaryOperation(Isolate* isolate,
|
||||||
@ -1858,7 +1858,7 @@ class UnaryOperation: public Expression {
|
|||||||
Expression* expression_;
|
Expression* expression_;
|
||||||
int pos_;
|
int pos_;
|
||||||
|
|
||||||
TypeInfo type_;
|
Handle<Type> type_;
|
||||||
|
|
||||||
// For unary not (Token::NOT), the AST ids where true and false will
|
// For unary not (Token::NOT), the AST ids where true and false will
|
||||||
// actually be materialized, respectively.
|
// actually be materialized, respectively.
|
||||||
@ -1882,9 +1882,9 @@ class BinaryOperation: public Expression {
|
|||||||
|
|
||||||
TypeFeedbackId BinaryOperationFeedbackId() const { return reuse(id()); }
|
TypeFeedbackId BinaryOperationFeedbackId() const { return reuse(id()); }
|
||||||
void RecordTypeFeedback(TypeFeedbackOracle* oracle);
|
void RecordTypeFeedback(TypeFeedbackOracle* oracle);
|
||||||
TypeInfo left_type() const { return left_type_; }
|
Handle<Type> left_type() const { return left_type_; }
|
||||||
TypeInfo right_type() const { return right_type_; }
|
Handle<Type> right_type() const { return right_type_; }
|
||||||
TypeInfo result_type() const { return result_type_; }
|
Handle<Type> result_type() const { return result_type_; }
|
||||||
bool has_fixed_right_arg() const { return has_fixed_right_arg_; }
|
bool has_fixed_right_arg() const { return has_fixed_right_arg_; }
|
||||||
int fixed_right_arg_value() const { return fixed_right_arg_value_; }
|
int fixed_right_arg_value() const { return fixed_right_arg_value_; }
|
||||||
|
|
||||||
@ -1909,9 +1909,9 @@ class BinaryOperation: public Expression {
|
|||||||
Expression* right_;
|
Expression* right_;
|
||||||
int pos_;
|
int pos_;
|
||||||
|
|
||||||
TypeInfo left_type_;
|
Handle<Type> left_type_;
|
||||||
TypeInfo right_type_;
|
Handle<Type> right_type_;
|
||||||
TypeInfo result_type_;
|
Handle<Type> result_type_;
|
||||||
bool has_fixed_right_arg_;
|
bool has_fixed_right_arg_;
|
||||||
int fixed_right_arg_value_;
|
int fixed_right_arg_value_;
|
||||||
|
|
||||||
|
@ -9106,11 +9106,11 @@ void HOptimizedGraphBuilder::VisitSub(UnaryOperation* expr) {
|
|||||||
HValue* context = environment()->LookupContext();
|
HValue* context = environment()->LookupContext();
|
||||||
HInstruction* instr =
|
HInstruction* instr =
|
||||||
HMul::New(zone(), context, value, graph()->GetConstantMinus1());
|
HMul::New(zone(), context, value, graph()->GetConstantMinus1());
|
||||||
TypeInfo info = expr->type();
|
Handle<Type> type = expr->type();
|
||||||
Representation rep = ToRepresentation(info);
|
Representation rep = ToRepresentation(type);
|
||||||
if (info.IsUninitialized()) {
|
if (type->Is(Type::None())) {
|
||||||
AddSoftDeoptimize();
|
AddSoftDeoptimize();
|
||||||
info = TypeInfo::Unknown();
|
type = handle(Type::Any(), isolate());
|
||||||
}
|
}
|
||||||
if (instr->IsBinaryOperation()) {
|
if (instr->IsBinaryOperation()) {
|
||||||
HBinaryOperation::cast(instr)->set_observed_input_representation(1, rep);
|
HBinaryOperation::cast(instr)->set_observed_input_representation(1, rep);
|
||||||
@ -9123,8 +9123,8 @@ void HOptimizedGraphBuilder::VisitSub(UnaryOperation* expr) {
|
|||||||
void HOptimizedGraphBuilder::VisitBitNot(UnaryOperation* expr) {
|
void HOptimizedGraphBuilder::VisitBitNot(UnaryOperation* expr) {
|
||||||
CHECK_ALIVE(VisitForValue(expr->expression()));
|
CHECK_ALIVE(VisitForValue(expr->expression()));
|
||||||
HValue* value = Pop();
|
HValue* value = Pop();
|
||||||
TypeInfo info = expr->type();
|
Handle<Type> info = expr->type();
|
||||||
if (info.IsUninitialized()) {
|
if (info->Is(Type::None())) {
|
||||||
AddSoftDeoptimize();
|
AddSoftDeoptimize();
|
||||||
}
|
}
|
||||||
HInstruction* instr = new(zone()) HBitNot(value);
|
HInstruction* instr = new(zone()) HBitNot(value);
|
||||||
@ -9486,24 +9486,26 @@ HInstruction* HOptimizedGraphBuilder::BuildBinaryOperation(
|
|||||||
HValue* left,
|
HValue* left,
|
||||||
HValue* right) {
|
HValue* right) {
|
||||||
HValue* context = environment()->LookupContext();
|
HValue* context = environment()->LookupContext();
|
||||||
TypeInfo left_info = expr->left_type();
|
Handle<Type> left_type = expr->left_type();
|
||||||
TypeInfo right_info = expr->right_type();
|
Handle<Type> right_type = expr->right_type();
|
||||||
TypeInfo result_info = expr->result_type();
|
Handle<Type> result_type = expr->result_type();
|
||||||
bool has_fixed_right_arg = expr->has_fixed_right_arg();
|
bool has_fixed_right_arg = expr->has_fixed_right_arg();
|
||||||
int fixed_right_arg_value = expr->fixed_right_arg_value();
|
int fixed_right_arg_value = expr->fixed_right_arg_value();
|
||||||
Representation left_rep = ToRepresentation(left_info);
|
Representation left_rep = ToRepresentation(left_type);
|
||||||
Representation right_rep = ToRepresentation(right_info);
|
Representation right_rep = ToRepresentation(right_type);
|
||||||
Representation result_rep = ToRepresentation(result_info);
|
Representation result_rep = ToRepresentation(result_type);
|
||||||
if (left_info.IsUninitialized()) {
|
if (left_type->Is(Type::None())) {
|
||||||
// Can't have initialized one but not the other.
|
|
||||||
ASSERT(right_info.IsUninitialized());
|
|
||||||
AddSoftDeoptimize();
|
AddSoftDeoptimize();
|
||||||
left_info = right_info = TypeInfo::Unknown();
|
left_type = handle(Type::Any(), isolate());
|
||||||
|
}
|
||||||
|
if (right_type->Is(Type::None())) {
|
||||||
|
AddSoftDeoptimize();
|
||||||
|
right_type = handle(Type::Any(), isolate());
|
||||||
}
|
}
|
||||||
HInstruction* instr = NULL;
|
HInstruction* instr = NULL;
|
||||||
switch (expr->op()) {
|
switch (expr->op()) {
|
||||||
case Token::ADD:
|
case Token::ADD:
|
||||||
if (left_info.IsString() && right_info.IsString()) {
|
if (left_type->Is(Type::String()) && right_type->Is(Type::String())) {
|
||||||
BuildCheckNonSmi(left);
|
BuildCheckNonSmi(left);
|
||||||
AddInstruction(HCheckInstanceType::NewIsString(left, zone()));
|
AddInstruction(HCheckInstanceType::NewIsString(left, zone()));
|
||||||
BuildCheckNonSmi(right);
|
BuildCheckNonSmi(right);
|
||||||
@ -9536,7 +9538,8 @@ HInstruction* HOptimizedGraphBuilder::BuildBinaryOperation(
|
|||||||
break;
|
break;
|
||||||
case Token::BIT_OR: {
|
case Token::BIT_OR: {
|
||||||
HValue* operand, *shift_amount;
|
HValue* operand, *shift_amount;
|
||||||
if (left_info.IsInteger32() && right_info.IsInteger32() &&
|
if (left_type->Is(Type::Integer32()) &&
|
||||||
|
right_type->Is(Type::Integer32()) &&
|
||||||
MatchRotateRight(left, right, &operand, &shift_amount)) {
|
MatchRotateRight(left, right, &operand, &shift_amount)) {
|
||||||
instr = new(zone()) HRor(context, operand, shift_amount);
|
instr = new(zone()) HRor(context, operand, shift_amount);
|
||||||
} else {
|
} else {
|
||||||
|
136
src/ic.cc
136
src/ic.cc
@ -2420,17 +2420,34 @@ const char* UnaryOpIC::GetName(TypeInfo type_info) {
|
|||||||
UnaryOpIC::State UnaryOpIC::ToState(TypeInfo type_info) {
|
UnaryOpIC::State UnaryOpIC::ToState(TypeInfo type_info) {
|
||||||
switch (type_info) {
|
switch (type_info) {
|
||||||
case UNINITIALIZED:
|
case UNINITIALIZED:
|
||||||
return ::v8::internal::UNINITIALIZED;
|
return v8::internal::UNINITIALIZED;
|
||||||
case SMI:
|
case SMI:
|
||||||
case NUMBER:
|
case NUMBER:
|
||||||
return MONOMORPHIC;
|
return MONOMORPHIC;
|
||||||
case GENERIC:
|
case GENERIC:
|
||||||
return ::v8::internal::GENERIC;
|
return v8::internal::GENERIC;
|
||||||
}
|
}
|
||||||
UNREACHABLE();
|
UNREACHABLE();
|
||||||
return ::v8::internal::UNINITIALIZED;
|
return v8::internal::UNINITIALIZED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Handle<Type> UnaryOpIC::TypeInfoToType(TypeInfo type_info, Isolate* isolate) {
|
||||||
|
switch (type_info) {
|
||||||
|
case UNINITIALIZED:
|
||||||
|
return handle(Type::None(), isolate);
|
||||||
|
case SMI:
|
||||||
|
return handle(Type::Integer31(), isolate);
|
||||||
|
case NUMBER:
|
||||||
|
return handle(Type::Number(), isolate);
|
||||||
|
case GENERIC:
|
||||||
|
return handle(Type::Any(), isolate);
|
||||||
|
}
|
||||||
|
UNREACHABLE();
|
||||||
|
return handle(Type::Any(), isolate);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
UnaryOpIC::TypeInfo UnaryOpIC::GetTypeInfo(Handle<Object> operand) {
|
UnaryOpIC::TypeInfo UnaryOpIC::GetTypeInfo(Handle<Object> operand) {
|
||||||
v8::internal::TypeInfo operand_type =
|
v8::internal::TypeInfo operand_type =
|
||||||
v8::internal::TypeInfo::FromValue(operand);
|
v8::internal::TypeInfo::FromValue(operand);
|
||||||
@ -2501,6 +2518,46 @@ BinaryOpIC::State BinaryOpIC::ToState(TypeInfo type_info) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Handle<Type> BinaryOpIC::TypeInfoToType(BinaryOpIC::TypeInfo binary_type,
|
||||||
|
Isolate* isolate) {
|
||||||
|
switch (binary_type) {
|
||||||
|
case UNINITIALIZED:
|
||||||
|
return handle(Type::None(), isolate);
|
||||||
|
case SMI:
|
||||||
|
return handle(Type::Integer31(), isolate);
|
||||||
|
case INT32:
|
||||||
|
return handle(Type::Integer32(), isolate);
|
||||||
|
case NUMBER:
|
||||||
|
return handle(Type::Number(), isolate);
|
||||||
|
case ODDBALL:
|
||||||
|
return handle(Type::Optional(
|
||||||
|
handle(Type::Union(
|
||||||
|
handle(Type::Number(), isolate),
|
||||||
|
handle(Type::String(), isolate)), isolate)), isolate);
|
||||||
|
case STRING:
|
||||||
|
return handle(Type::String(), isolate);
|
||||||
|
case GENERIC:
|
||||||
|
return handle(Type::Any(), isolate);
|
||||||
|
}
|
||||||
|
UNREACHABLE();
|
||||||
|
return handle(Type::Any(), isolate);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void BinaryOpIC::StubInfoToType(int minor_key,
|
||||||
|
Handle<Type>* left,
|
||||||
|
Handle<Type>* right,
|
||||||
|
Handle<Type>* result,
|
||||||
|
Isolate* isolate) {
|
||||||
|
TypeInfo left_typeinfo, right_typeinfo, result_typeinfo;
|
||||||
|
BinaryOpStub::decode_types_from_minor_key(
|
||||||
|
minor_key, &left_typeinfo, &right_typeinfo, &result_typeinfo);
|
||||||
|
*left = TypeInfoToType(left_typeinfo, isolate);
|
||||||
|
*right = TypeInfoToType(right_typeinfo, isolate);
|
||||||
|
*result = TypeInfoToType(result_typeinfo, isolate);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
RUNTIME_FUNCTION(MaybeObject*, UnaryOp_Patch) {
|
RUNTIME_FUNCTION(MaybeObject*, UnaryOp_Patch) {
|
||||||
ASSERT(args.length() == 4);
|
ASSERT(args.length() == 4);
|
||||||
|
|
||||||
@ -2814,45 +2871,60 @@ Handle<Type> CompareIC::StateToType(
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static CompareIC::State InputState(CompareIC::State old_state,
|
void CompareIC::StubInfoToType(int stub_minor_key,
|
||||||
Handle<Object> value) {
|
Handle<Type>* left_type,
|
||||||
|
Handle<Type>* right_type,
|
||||||
|
Handle<Type>* overall_type,
|
||||||
|
Handle<Map> map,
|
||||||
|
Isolate* isolate) {
|
||||||
|
State left_state, right_state, handler_state;
|
||||||
|
ICCompareStub::DecodeMinorKey(stub_minor_key, &left_state, &right_state,
|
||||||
|
&handler_state, NULL);
|
||||||
|
*left_type = StateToType(isolate, left_state);
|
||||||
|
*right_type = StateToType(isolate, right_state);
|
||||||
|
*overall_type = StateToType(isolate, handler_state, map);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
CompareIC::State CompareIC::NewInputState(State old_state,
|
||||||
|
Handle<Object> value) {
|
||||||
switch (old_state) {
|
switch (old_state) {
|
||||||
case CompareIC::UNINITIALIZED:
|
case UNINITIALIZED:
|
||||||
if (value->IsSmi()) return CompareIC::SMI;
|
if (value->IsSmi()) return SMI;
|
||||||
if (value->IsHeapNumber()) return CompareIC::NUMBER;
|
if (value->IsHeapNumber()) return NUMBER;
|
||||||
if (value->IsInternalizedString()) return CompareIC::INTERNALIZED_STRING;
|
if (value->IsInternalizedString()) return INTERNALIZED_STRING;
|
||||||
if (value->IsString()) return CompareIC::STRING;
|
if (value->IsString()) return STRING;
|
||||||
if (value->IsSymbol()) return CompareIC::UNIQUE_NAME;
|
if (value->IsSymbol()) return UNIQUE_NAME;
|
||||||
if (value->IsJSObject()) return CompareIC::OBJECT;
|
if (value->IsJSObject()) return OBJECT;
|
||||||
break;
|
break;
|
||||||
case CompareIC::SMI:
|
case SMI:
|
||||||
if (value->IsSmi()) return CompareIC::SMI;
|
if (value->IsSmi()) return SMI;
|
||||||
if (value->IsHeapNumber()) return CompareIC::NUMBER;
|
if (value->IsHeapNumber()) return NUMBER;
|
||||||
break;
|
break;
|
||||||
case CompareIC::NUMBER:
|
case NUMBER:
|
||||||
if (value->IsNumber()) return CompareIC::NUMBER;
|
if (value->IsNumber()) return NUMBER;
|
||||||
break;
|
break;
|
||||||
case CompareIC::INTERNALIZED_STRING:
|
case INTERNALIZED_STRING:
|
||||||
if (value->IsInternalizedString()) return CompareIC::INTERNALIZED_STRING;
|
if (value->IsInternalizedString()) return INTERNALIZED_STRING;
|
||||||
if (value->IsString()) return CompareIC::STRING;
|
if (value->IsString()) return STRING;
|
||||||
if (value->IsSymbol()) return CompareIC::UNIQUE_NAME;
|
if (value->IsSymbol()) return UNIQUE_NAME;
|
||||||
break;
|
break;
|
||||||
case CompareIC::STRING:
|
case STRING:
|
||||||
if (value->IsString()) return CompareIC::STRING;
|
if (value->IsString()) return STRING;
|
||||||
break;
|
break;
|
||||||
case CompareIC::UNIQUE_NAME:
|
case UNIQUE_NAME:
|
||||||
if (value->IsUniqueName()) return CompareIC::UNIQUE_NAME;
|
if (value->IsUniqueName()) return UNIQUE_NAME;
|
||||||
break;
|
break;
|
||||||
case CompareIC::OBJECT:
|
case OBJECT:
|
||||||
if (value->IsJSObject()) return CompareIC::OBJECT;
|
if (value->IsJSObject()) return OBJECT;
|
||||||
break;
|
break;
|
||||||
case CompareIC::GENERIC:
|
case GENERIC:
|
||||||
break;
|
break;
|
||||||
case CompareIC::KNOWN_OBJECT:
|
case KNOWN_OBJECT:
|
||||||
UNREACHABLE();
|
UNREACHABLE();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return CompareIC::GENERIC;
|
return GENERIC;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -2925,8 +2997,8 @@ void CompareIC::UpdateCaches(Handle<Object> x, Handle<Object> y) {
|
|||||||
State previous_left, previous_right, previous_state;
|
State previous_left, previous_right, previous_state;
|
||||||
ICCompareStub::DecodeMinorKey(target()->stub_info(), &previous_left,
|
ICCompareStub::DecodeMinorKey(target()->stub_info(), &previous_left,
|
||||||
&previous_right, &previous_state, NULL);
|
&previous_right, &previous_state, NULL);
|
||||||
State new_left = InputState(previous_left, x);
|
State new_left = NewInputState(previous_left, x);
|
||||||
State new_right = InputState(previous_right, y);
|
State new_right = NewInputState(previous_right, y);
|
||||||
State state = TargetState(previous_state, previous_left, previous_right,
|
State state = TargetState(previous_state, previous_left, previous_right,
|
||||||
HasInlinedSmiCode(address()), x, y);
|
HasInlinedSmiCode(address()), x, y);
|
||||||
ICCompareStub stub(op_, new_left, new_right, state);
|
ICCompareStub stub(op_, new_left, new_right, state);
|
||||||
|
25
src/ic.h
25
src/ic.h
@ -690,6 +690,8 @@ class UnaryOpIC: public IC {
|
|||||||
GENERIC
|
GENERIC
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static Handle<Type> TypeInfoToType(TypeInfo info, Isolate* isolate);
|
||||||
|
|
||||||
explicit UnaryOpIC(Isolate* isolate) : IC(NO_EXTRA_FRAME, isolate) { }
|
explicit UnaryOpIC(Isolate* isolate) : IC(NO_EXTRA_FRAME, isolate) { }
|
||||||
|
|
||||||
void patch(Code* code);
|
void patch(Code* code);
|
||||||
@ -717,6 +719,12 @@ class BinaryOpIC: public IC {
|
|||||||
GENERIC
|
GENERIC
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static void StubInfoToType(int minor_key,
|
||||||
|
Handle<Type>* left,
|
||||||
|
Handle<Type>* right,
|
||||||
|
Handle<Type>* result,
|
||||||
|
Isolate* isolate);
|
||||||
|
|
||||||
explicit BinaryOpIC(Isolate* isolate) : IC(NO_EXTRA_FRAME, isolate) { }
|
explicit BinaryOpIC(Isolate* isolate) : IC(NO_EXTRA_FRAME, isolate) { }
|
||||||
|
|
||||||
void patch(Code* code);
|
void patch(Code* code);
|
||||||
@ -724,6 +732,9 @@ class BinaryOpIC: public IC {
|
|||||||
static const char* GetName(TypeInfo type_info);
|
static const char* GetName(TypeInfo type_info);
|
||||||
|
|
||||||
static State ToState(TypeInfo type_info);
|
static State ToState(TypeInfo type_info);
|
||||||
|
|
||||||
|
private:
|
||||||
|
static Handle<Type> TypeInfoToType(TypeInfo binary_type, Isolate* isolate);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -747,8 +758,18 @@ class CompareIC: public IC {
|
|||||||
GENERIC
|
GENERIC
|
||||||
};
|
};
|
||||||
|
|
||||||
static Handle<Type> StateToType(
|
static State NewInputState(State old_state, Handle<Object> value);
|
||||||
Isolate* isolate, State state, Handle<Map> map = Handle<Map>());
|
|
||||||
|
static Handle<Type> StateToType(Isolate* isolate,
|
||||||
|
State state,
|
||||||
|
Handle<Map> map = Handle<Map>());
|
||||||
|
|
||||||
|
static void StubInfoToType(int stub_minor_key,
|
||||||
|
Handle<Type>* left_type,
|
||||||
|
Handle<Type>* right_type,
|
||||||
|
Handle<Type>* overall_type,
|
||||||
|
Handle<Map> map,
|
||||||
|
Isolate* isolate);
|
||||||
|
|
||||||
CompareIC(Isolate* isolate, Token::Value op)
|
CompareIC(Isolate* isolate, Token::Value op)
|
||||||
: IC(EXTRA_CALL_FRAME, isolate), op_(op) { }
|
: IC(EXTRA_CALL_FRAME, isolate), op_(op) { }
|
||||||
|
@ -363,12 +363,8 @@ void TypeFeedbackOracle::CompareTypes(TypeFeedbackId id,
|
|||||||
|
|
||||||
if (code->is_compare_ic_stub()) {
|
if (code->is_compare_ic_stub()) {
|
||||||
int stub_minor_key = code->stub_info();
|
int stub_minor_key = code->stub_info();
|
||||||
CompareIC::State left_state, right_state, handler_state;
|
CompareIC::StubInfoToType(
|
||||||
ICCompareStub::DecodeMinorKey(stub_minor_key, &left_state, &right_state,
|
stub_minor_key, left_type, right_type, overall_type, map, isolate());
|
||||||
&handler_state, NULL);
|
|
||||||
*left_type = CompareIC::StateToType(isolate_, left_state);
|
|
||||||
*right_type = CompareIC::StateToType(isolate_, right_state);
|
|
||||||
*overall_type = CompareIC::StateToType(isolate_, handler_state, map);
|
|
||||||
} else if (code->is_compare_nil_ic_stub()) {
|
} else if (code->is_compare_nil_ic_stub()) {
|
||||||
CompareNilICStub::State state(code->compare_nil_state());
|
CompareNilICStub::State state(code->compare_nil_state());
|
||||||
*compare_nil_type = CompareNilICStub::StateToType(isolate_, state, map);
|
*compare_nil_type = CompareNilICStub::StateToType(isolate_, state, map);
|
||||||
@ -376,70 +372,34 @@ void TypeFeedbackOracle::CompareTypes(TypeFeedbackId id,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
TypeInfo TypeFeedbackOracle::UnaryType(UnaryOperation* expr) {
|
Handle<Type> TypeFeedbackOracle::UnaryType(TypeFeedbackId id) {
|
||||||
Handle<Object> object = GetInfo(expr->UnaryOperationFeedbackId());
|
Handle<Object> object = GetInfo(id);
|
||||||
TypeInfo unknown = TypeInfo::Unknown();
|
if (!object->IsCode()) return handle(Type::Any(), isolate());
|
||||||
if (!object->IsCode()) return unknown;
|
|
||||||
Handle<Code> code = Handle<Code>::cast(object);
|
Handle<Code> code = Handle<Code>::cast(object);
|
||||||
ASSERT(code->is_unary_op_stub());
|
ASSERT(code->is_unary_op_stub());
|
||||||
UnaryOpIC::TypeInfo type = static_cast<UnaryOpIC::TypeInfo>(
|
return UnaryOpIC::TypeInfoToType(
|
||||||
code->unary_op_type());
|
static_cast<UnaryOpIC::TypeInfo>(code->unary_op_type()), isolate());
|
||||||
switch (type) {
|
|
||||||
case UnaryOpIC::SMI:
|
|
||||||
return TypeInfo::Smi();
|
|
||||||
case UnaryOpIC::NUMBER:
|
|
||||||
return TypeInfo::Double();
|
|
||||||
default:
|
|
||||||
return unknown;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static TypeInfo TypeFromBinaryOpType(BinaryOpIC::TypeInfo binary_type) {
|
void TypeFeedbackOracle::BinaryType(TypeFeedbackId id,
|
||||||
switch (binary_type) {
|
Handle<Type>* left,
|
||||||
// Uninitialized means never executed.
|
Handle<Type>* right,
|
||||||
case BinaryOpIC::UNINITIALIZED: return TypeInfo::Uninitialized();
|
Handle<Type>* result,
|
||||||
case BinaryOpIC::SMI: return TypeInfo::Smi();
|
|
||||||
case BinaryOpIC::INT32: return TypeInfo::Integer32();
|
|
||||||
case BinaryOpIC::NUMBER: return TypeInfo::Double();
|
|
||||||
case BinaryOpIC::ODDBALL: return TypeInfo::Unknown();
|
|
||||||
case BinaryOpIC::STRING: return TypeInfo::String();
|
|
||||||
case BinaryOpIC::GENERIC: return TypeInfo::Unknown();
|
|
||||||
}
|
|
||||||
UNREACHABLE();
|
|
||||||
return TypeInfo::Unknown();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void TypeFeedbackOracle::BinaryType(BinaryOperation* expr,
|
|
||||||
TypeInfo* left,
|
|
||||||
TypeInfo* right,
|
|
||||||
TypeInfo* result,
|
|
||||||
bool* has_fixed_right_arg,
|
bool* has_fixed_right_arg,
|
||||||
int* fixed_right_arg_value) {
|
int* fixed_right_arg_value) {
|
||||||
Handle<Object> object = GetInfo(expr->BinaryOperationFeedbackId());
|
Handle<Object> object = GetInfo(id);
|
||||||
TypeInfo unknown = TypeInfo::Unknown();
|
*left = *right = *result = handle(Type::Any(), isolate_);
|
||||||
if (!object->IsCode()) {
|
if (!object->IsCode()) return;
|
||||||
*left = *right = *result = unknown;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
Handle<Code> code = Handle<Code>::cast(object);
|
Handle<Code> code = Handle<Code>::cast(object);
|
||||||
if (code->is_binary_op_stub()) {
|
if (!code->is_binary_op_stub()) return;
|
||||||
int minor_key = code->stub_info();
|
|
||||||
BinaryOpIC::TypeInfo left_type, right_type, result_type;
|
int minor_key = code->stub_info();
|
||||||
BinaryOpStub::decode_types_from_minor_key(
|
BinaryOpIC::StubInfoToType(minor_key, left, right, result, isolate());
|
||||||
minor_key, &left_type, &right_type, &result_type);
|
*has_fixed_right_arg =
|
||||||
*left = TypeFromBinaryOpType(left_type);
|
BinaryOpStub::decode_has_fixed_right_arg_from_minor_key(minor_key);
|
||||||
*right = TypeFromBinaryOpType(right_type);
|
*fixed_right_arg_value =
|
||||||
*result = TypeFromBinaryOpType(result_type);
|
BinaryOpStub::decode_fixed_right_arg_value_from_minor_key(minor_key);
|
||||||
*has_fixed_right_arg =
|
|
||||||
BinaryOpStub::decode_has_fixed_right_arg_from_minor_key(minor_key);
|
|
||||||
*fixed_right_arg_value =
|
|
||||||
BinaryOpStub::decode_fixed_right_arg_value_from_minor_key(minor_key);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// Not a binary op stub.
|
|
||||||
*left = *right = *result = unknown;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -220,7 +220,6 @@ enum StringStubFeedback {
|
|||||||
// Forward declarations.
|
// Forward declarations.
|
||||||
// TODO(rossberg): these should all go away eventually.
|
// TODO(rossberg): these should all go away eventually.
|
||||||
class Assignment;
|
class Assignment;
|
||||||
class BinaryOperation;
|
|
||||||
class Call;
|
class Call;
|
||||||
class CallNew;
|
class CallNew;
|
||||||
class CaseClause;
|
class CaseClause;
|
||||||
@ -231,7 +230,6 @@ class ForInStatement;
|
|||||||
class ICStub;
|
class ICStub;
|
||||||
class Property;
|
class Property;
|
||||||
class SmallMapList;
|
class SmallMapList;
|
||||||
class UnaryOperation;
|
|
||||||
class ObjectLiteral;
|
class ObjectLiteral;
|
||||||
class ObjectLiteralProperty;
|
class ObjectLiteralProperty;
|
||||||
|
|
||||||
@ -296,11 +294,11 @@ class TypeFeedbackOracle: public ZoneObject {
|
|||||||
byte ToBooleanTypes(TypeFeedbackId id);
|
byte ToBooleanTypes(TypeFeedbackId id);
|
||||||
|
|
||||||
// Get type information for arithmetic operations and compares.
|
// Get type information for arithmetic operations and compares.
|
||||||
TypeInfo UnaryType(UnaryOperation* expr);
|
Handle<Type> UnaryType(TypeFeedbackId id);
|
||||||
void BinaryType(BinaryOperation* expr,
|
void BinaryType(TypeFeedbackId id,
|
||||||
TypeInfo* left,
|
Handle<Type>* left,
|
||||||
TypeInfo* right,
|
Handle<Type>* right,
|
||||||
TypeInfo* result,
|
Handle<Type>* result,
|
||||||
bool* has_fixed_right_arg,
|
bool* has_fixed_right_arg,
|
||||||
int* fixed_right_arg_value);
|
int* fixed_right_arg_value);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user