Index: src/type-info.cc |
diff --git a/src/type-info.cc b/src/type-info.cc |
index 8719439ad4616aee939cdf02446a9a38b794b63c..cd5266133f012c42e639521bbb590fcb22bbfcfc 100644 |
--- a/src/type-info.cc |
+++ b/src/type-info.cc |
@@ -58,7 +58,9 @@ TypeInfo TypeInfo::TypeFromValue(Handle<Object> value) { |
} |
-TypeFeedbackOracle::TypeFeedbackOracle(Handle<Code> code) { |
+TypeFeedbackOracle::TypeFeedbackOracle(Handle<Code> code, |
+ Handle<Context> global_context) { |
+ global_context_ = global_context; |
Initialize(code); |
} |
@@ -81,7 +83,8 @@ bool TypeFeedbackOracle:: StoreIsMonomorphic(Assignment* expr) { |
bool TypeFeedbackOracle::CallIsMonomorphic(Call* expr) { |
- return IsMonomorphic(expr->position()); |
+ Handle<Object> value = GetElement(map_, expr->position()); |
+ return value->IsMap() || value->IsSmi(); |
} |
@@ -97,12 +100,6 @@ Handle<Map> TypeFeedbackOracle::StoreMonomorphicReceiverType(Assignment* expr) { |
} |
-Handle<Map> TypeFeedbackOracle::CallMonomorphicReceiverType(Call* expr) { |
- ASSERT(CallIsMonomorphic(expr)); |
- return Handle<Map>::cast(GetElement(map_, expr->position())); |
-} |
- |
- |
ZoneMapList* TypeFeedbackOracle::LoadReceiverTypes(Property* expr, |
Handle<String> name) { |
Code::Flags flags = Code::ComputeMonomorphicFlags(Code::LOAD_IC, NORMAL); |
@@ -126,6 +123,37 @@ ZoneMapList* TypeFeedbackOracle::CallReceiverTypes(Call* expr, |
} |
+CheckType TypeFeedbackOracle::GetCallCheckType(Call* expr) { |
+ Handle<Object> value = GetElement(map_, expr->position()); |
+ if (!value->IsSmi()) return RECEIVER_MAP_CHECK; |
+ CheckType check = static_cast<CheckType>(Smi::cast(*value)->value()); |
+ ASSERT(check != RECEIVER_MAP_CHECK); |
+ return check; |
+} |
+ |
+ |
+Handle<JSObject> TypeFeedbackOracle::GetPrototypeForPrimitiveCheck( |
+ CheckType check) { |
+ JSFunction* function = NULL; |
+ switch (check) { |
+ case RECEIVER_MAP_CHECK: |
+ UNREACHABLE(); |
+ break; |
+ case STRING_CHECK: |
+ function = global_context_->string_function(); |
+ break; |
+ case NUMBER_CHECK: |
+ function = global_context_->number_function(); |
+ break; |
+ case BOOLEAN_CHECK: |
+ function = global_context_->boolean_function(); |
+ break; |
+ } |
+ ASSERT(function != NULL); |
+ return Handle<JSObject>(JSObject::cast(function->instance_prototype())); |
+} |
+ |
+ |
bool TypeFeedbackOracle::LoadIsBuiltin(Property* expr, Builtins::Name id) { |
Handle<Object> object = GetElement(map_, expr->position()); |
return *object == Builtins::builtin(id); |
@@ -220,6 +248,7 @@ TypeInfo TypeFeedbackOracle::BinaryType(BinaryOperation* expr, Side side) { |
return unknown; |
} |
+ |
TypeInfo TypeFeedbackOracle::SwitchType(CaseClause* clause) { |
Handle<Object> object = GetElement(map_, clause->position()); |
TypeInfo unknown = TypeInfo::Unknown(); |
@@ -247,12 +276,11 @@ TypeInfo TypeFeedbackOracle::SwitchType(CaseClause* clause) { |
} |
- |
ZoneMapList* TypeFeedbackOracle::CollectReceiverTypes(int position, |
Handle<String> name, |
Code::Flags flags) { |
Handle<Object> object = GetElement(map_, position); |
- if (object->IsUndefined()) return NULL; |
+ if (object->IsUndefined() || object->IsSmi()) return NULL; |
if (*object == Builtins::builtin(Builtins::StoreIC_GlobalProxy)) { |
// TODO(fschneider): We could collect the maps and signal that |
@@ -301,11 +329,20 @@ void TypeFeedbackOracle::PopulateMap(Handle<Code> code) { |
SetElement(map_, position, target); |
} |
} else if (state == MONOMORPHIC) { |
- Handle<Map> map = Handle<Map>(target->FindFirstMap()); |
- if (*map == NULL) { |
- SetElement(map_, position, target); |
+ if (target->kind() != Code::CALL_IC || |
+ target->check_type() == RECEIVER_MAP_CHECK) { |
+ Handle<Map> map = Handle<Map>(target->FindFirstMap()); |
+ if (*map == NULL) { |
+ SetElement(map_, position, target); |
+ } else { |
+ SetElement(map_, position, map); |
+ } |
} else { |
- SetElement(map_, position, map); |
+ ASSERT(target->kind() == Code::CALL_IC); |
+ CheckType check = target->check_type(); |
+ ASSERT(check != RECEIVER_MAP_CHECK); |
+ SetElement(map_, position, Handle<Object>(Smi::FromInt(check))); |
+ ASSERT(Smi::cast(*GetElement(map_, position))->value() == check); |
} |
} else if (state == MEGAMORPHIC) { |
SetElement(map_, position, target); |
@@ -342,8 +379,6 @@ void TypeFeedbackOracle::CollectPositions(Code* code, |
} else if (kind == Code::COMPARE_IC) { |
if (target->compare_state() == CompareIC::GENERIC) continue; |
} else { |
- if (kind == Code::CALL_IC && state == MONOMORPHIC && |
- target->check_type() != RECEIVER_MAP_CHECK) continue; |
if (state != MONOMORPHIC && state != MEGAMORPHIC) continue; |
} |
code_positions->Add( |