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; |