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