| Index: src/type-info.cc
|
| diff --git a/src/type-info.cc b/src/type-info.cc
|
| index bc6a46b4b664f095e6587ed8fa873df9868b5093..f97fb52af31d6c581aee013bc86157c818b9e77c 100644
|
| --- a/src/type-info.cc
|
| +++ b/src/type-info.cc
|
| @@ -312,43 +312,53 @@ bool TypeFeedbackOracle::LoadIsBuiltin(Property* expr, Builtins::Name id) {
|
| }
|
|
|
|
|
| -TypeInfo TypeFeedbackOracle::CompareType(CompareOperation* expr) {
|
| - Handle<Object> object = GetInfo(expr->CompareOperationFeedbackId());
|
| - TypeInfo unknown = TypeInfo::Unknown();
|
| - if (!object->IsCode()) return unknown;
|
| - Handle<Code> code = Handle<Code>::cast(object);
|
| - if (!code->is_compare_ic_stub()) return unknown;
|
| -
|
| - CompareIC::State state = static_cast<CompareIC::State>(code->compare_state());
|
| +static TypeInfo TypeFromCompareType(CompareIC::State state) {
|
| switch (state) {
|
| case CompareIC::UNINITIALIZED:
|
| // Uninitialized means never executed.
|
| return TypeInfo::Uninitialized();
|
| - case CompareIC::SMIS:
|
| + case CompareIC::SMI:
|
| return TypeInfo::Smi();
|
| - case CompareIC::HEAP_NUMBERS:
|
| + case CompareIC::HEAP_NUMBER:
|
| return TypeInfo::Number();
|
| - case CompareIC::SYMBOLS:
|
| - case CompareIC::STRINGS:
|
| + case CompareIC::SYMBOL:
|
| + return TypeInfo::Symbol();
|
| + case CompareIC::STRING:
|
| return TypeInfo::String();
|
| - case CompareIC::OBJECTS:
|
| + case CompareIC::OBJECT:
|
| case CompareIC::KNOWN_OBJECTS:
|
| // TODO(kasperl): We really need a type for JS objects here.
|
| return TypeInfo::NonPrimitive();
|
| case CompareIC::GENERIC:
|
| default:
|
| - return unknown;
|
| + return TypeInfo::Unknown();
|
| }
|
| }
|
|
|
|
|
| -bool TypeFeedbackOracle::IsSymbolCompare(CompareOperation* expr) {
|
| +void TypeFeedbackOracle::CompareType(CompareOperation* expr,
|
| + TypeInfo* left_type,
|
| + TypeInfo* right_type,
|
| + TypeInfo* overall_type) {
|
| Handle<Object> object = GetInfo(expr->CompareOperationFeedbackId());
|
| - if (!object->IsCode()) return false;
|
| + TypeInfo unknown = TypeInfo::Unknown();
|
| + if (!object->IsCode()) {
|
| + *left_type = *right_type = *overall_type = unknown;
|
| + return;
|
| + }
|
| Handle<Code> code = Handle<Code>::cast(object);
|
| - if (!code->is_compare_ic_stub()) return false;
|
| - CompareIC::State state = static_cast<CompareIC::State>(code->compare_state());
|
| - return state == CompareIC::SYMBOLS;
|
| + if (!code->is_compare_ic_stub()) {
|
| + *left_type = *right_type = *overall_type = unknown;
|
| + return;
|
| + }
|
| +
|
| + int stub_minor_key = code->stub_info();
|
| + CompareIC::State left_state, right_state, handler_state;
|
| + ICCompareStub::DecodeMinorKey(stub_minor_key, &left_state, &right_state,
|
| + &handler_state, NULL);
|
| + *left_type = TypeFromCompareType(left_state);
|
| + *right_type = TypeFromCompareType(right_state);
|
| + *overall_type = TypeFromCompareType(handler_state);
|
| }
|
|
|
|
|
| @@ -357,7 +367,7 @@ Handle<Map> TypeFeedbackOracle::GetCompareMap(CompareOperation* expr) {
|
| if (!object->IsCode()) return Handle<Map>::null();
|
| Handle<Code> code = Handle<Code>::cast(object);
|
| if (!code->is_compare_ic_stub()) return Handle<Map>::null();
|
| - CompareIC::State state = static_cast<CompareIC::State>(code->compare_state());
|
| + CompareIC::State state = ICCompareStub::CompareState(code->stub_info());
|
| if (state != CompareIC::KNOWN_OBJECTS) {
|
| return Handle<Map>::null();
|
| }
|
| @@ -388,55 +398,44 @@ TypeInfo TypeFeedbackOracle::UnaryType(UnaryOperation* expr) {
|
| }
|
|
|
|
|
| -TypeInfo TypeFeedbackOracle::BinaryType(BinaryOperation* expr) {
|
| +static TypeInfo TypeFromBinaryOpType(BinaryOpIC::TypeInfo binary_type) {
|
| + switch (binary_type) {
|
| + // Uninitialized means never executed.
|
| + case BinaryOpIC::UNINITIALIZED: return TypeInfo::Uninitialized();
|
| + case BinaryOpIC::SMI: return TypeInfo::Smi();
|
| + case BinaryOpIC::INT32: return TypeInfo::Integer32();
|
| + case BinaryOpIC::HEAP_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) {
|
| Handle<Object> object = GetInfo(expr->BinaryOperationFeedbackId());
|
| TypeInfo unknown = TypeInfo::Unknown();
|
| - if (!object->IsCode()) return unknown;
|
| + if (!object->IsCode()) {
|
| + *left = *right = *result = unknown;
|
| + return;
|
| + }
|
| Handle<Code> code = Handle<Code>::cast(object);
|
| if (code->is_binary_op_stub()) {
|
| - BinaryOpIC::TypeInfo type = static_cast<BinaryOpIC::TypeInfo>(
|
| - code->binary_op_type());
|
| - BinaryOpIC::TypeInfo result_type = static_cast<BinaryOpIC::TypeInfo>(
|
| - code->binary_op_result_type());
|
| -
|
| - switch (type) {
|
| - case BinaryOpIC::UNINITIALIZED:
|
| - // Uninitialized means never executed.
|
| - return TypeInfo::Uninitialized();
|
| - case BinaryOpIC::SMI:
|
| - switch (result_type) {
|
| - case BinaryOpIC::UNINITIALIZED:
|
| - if (expr->op() == Token::DIV) {
|
| - return TypeInfo::Double();
|
| - }
|
| - return TypeInfo::Smi();
|
| - case BinaryOpIC::SMI:
|
| - return TypeInfo::Smi();
|
| - case BinaryOpIC::INT32:
|
| - return TypeInfo::Integer32();
|
| - case BinaryOpIC::HEAP_NUMBER:
|
| - return TypeInfo::Double();
|
| - default:
|
| - return unknown;
|
| - }
|
| - case BinaryOpIC::INT32:
|
| - if (expr->op() == Token::DIV ||
|
| - result_type == BinaryOpIC::HEAP_NUMBER) {
|
| - return TypeInfo::Double();
|
| - }
|
| - return TypeInfo::Integer32();
|
| - case BinaryOpIC::HEAP_NUMBER:
|
| - return TypeInfo::Double();
|
| - case BinaryOpIC::BOTH_STRING:
|
| - return TypeInfo::String();
|
| - case BinaryOpIC::STRING:
|
| - case BinaryOpIC::GENERIC:
|
| - return unknown;
|
| - default:
|
| - return unknown;
|
| - }
|
| + BinaryOpIC::TypeInfo left_type, right_type, result_type;
|
| + BinaryOpStub::decode_types_from_minor_key(code->stub_info(), &left_type,
|
| + &right_type, &result_type);
|
| + *left = TypeFromBinaryOpType(left_type);
|
| + *right = TypeFromBinaryOpType(right_type);
|
| + *result = TypeFromBinaryOpType(result_type);
|
| + return;
|
| }
|
| - return unknown;
|
| + // Not a binary op stub.
|
| + *left = *right = *result = unknown;
|
| }
|
|
|
|
|
| @@ -447,28 +446,8 @@ TypeInfo TypeFeedbackOracle::SwitchType(CaseClause* clause) {
|
| Handle<Code> code = Handle<Code>::cast(object);
|
| if (!code->is_compare_ic_stub()) return unknown;
|
|
|
| - CompareIC::State state = static_cast<CompareIC::State>(code->compare_state());
|
| - switch (state) {
|
| - case CompareIC::UNINITIALIZED:
|
| - // Uninitialized means never executed.
|
| - // TODO(fschneider): Introduce a separate value for never-executed ICs.
|
| - return unknown;
|
| - case CompareIC::SMIS:
|
| - return TypeInfo::Smi();
|
| - case CompareIC::STRINGS:
|
| - return TypeInfo::String();
|
| - case CompareIC::SYMBOLS:
|
| - return TypeInfo::Symbol();
|
| - case CompareIC::HEAP_NUMBERS:
|
| - return TypeInfo::Number();
|
| - case CompareIC::OBJECTS:
|
| - case CompareIC::KNOWN_OBJECTS:
|
| - // TODO(kasperl): We really need a type for JS objects here.
|
| - return TypeInfo::NonPrimitive();
|
| - case CompareIC::GENERIC:
|
| - default:
|
| - return unknown;
|
| - }
|
| + CompareIC::State state = ICCompareStub::CompareState(code->stub_info());
|
| + return TypeFromCompareType(state);
|
| }
|
|
|
|
|
| @@ -479,9 +458,14 @@ TypeInfo TypeFeedbackOracle::IncrementType(CountOperation* expr) {
|
| Handle<Code> code = Handle<Code>::cast(object);
|
| if (!code->is_binary_op_stub()) return unknown;
|
|
|
| - BinaryOpIC::TypeInfo type = static_cast<BinaryOpIC::TypeInfo>(
|
| - code->binary_op_type());
|
| - switch (type) {
|
| + BinaryOpIC::TypeInfo left_type, right_type, unused_result_type;
|
| + BinaryOpStub::decode_types_from_minor_key(code->stub_info(), &left_type,
|
| + &right_type, &unused_result_type);
|
| + // CountOperations should always have +1 or -1 as their right input.
|
| + ASSERT(right_type == BinaryOpIC::SMI ||
|
| + right_type == BinaryOpIC::UNINITIALIZED);
|
| +
|
| + switch (left_type) {
|
| case BinaryOpIC::UNINITIALIZED:
|
| case BinaryOpIC::SMI:
|
| return TypeInfo::Smi();
|
| @@ -489,7 +473,6 @@ TypeInfo TypeFeedbackOracle::IncrementType(CountOperation* expr) {
|
| return TypeInfo::Integer32();
|
| case BinaryOpIC::HEAP_NUMBER:
|
| return TypeInfo::Double();
|
| - case BinaryOpIC::BOTH_STRING:
|
| case BinaryOpIC::STRING:
|
| case BinaryOpIC::GENERIC:
|
| return unknown;
|
|
|