Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(51)

Unified Diff: src/type-info.cc

Issue 10837165: Lattice-based representation inference, powered by left/right specific type feedback for BinaryOps … (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: review feedback; fixed tests Created 8 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/type-info.h ('k') | src/x64/code-stubs-x64.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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;
« no previous file with comments | « src/type-info.h ('k') | src/x64/code-stubs-x64.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698