| Index: src/type-info.cc
|
| ===================================================================
|
| --- src/type-info.cc (revision 6800)
|
| +++ src/type-info.cc (working copy)
|
| @@ -58,7 +58,12 @@
|
| }
|
|
|
|
|
| -TypeFeedbackOracle::TypeFeedbackOracle(Handle<Code> code) {
|
| +STATIC_ASSERT(DEFAULT_STRING_STUB == Code::kNoExtraICState);
|
| +
|
| +
|
| +TypeFeedbackOracle::TypeFeedbackOracle(Handle<Code> code,
|
| + Handle<Context> global_context) {
|
| + global_context_ = global_context;
|
| Initialize(code);
|
| }
|
|
|
| @@ -71,17 +76,18 @@
|
|
|
|
|
| bool TypeFeedbackOracle::LoadIsMonomorphic(Property* expr) {
|
| - return IsMonomorphic(expr->position());
|
| + return GetElement(map_, expr->position())->IsMap();
|
| }
|
|
|
|
|
| bool TypeFeedbackOracle:: StoreIsMonomorphic(Assignment* expr) {
|
| - return IsMonomorphic(expr->position());
|
| + return GetElement(map_, expr->position())->IsMap();
|
| }
|
|
|
|
|
| bool TypeFeedbackOracle::CallIsMonomorphic(Call* expr) {
|
| - return IsMonomorphic(expr->position());
|
| + Handle<Object> value = GetElement(map_, expr->position());
|
| + return value->IsMap() || value->IsSmi();
|
| }
|
|
|
|
|
| @@ -97,12 +103,6 @@
|
| }
|
|
|
|
|
| -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);
|
| @@ -120,19 +120,58 @@
|
| ZoneMapList* TypeFeedbackOracle::CallReceiverTypes(Call* expr,
|
| Handle<String> name) {
|
| int arity = expr->arguments()->length();
|
| - Code::Flags flags = Code::ComputeMonomorphicFlags(
|
| - Code::CALL_IC, NORMAL, OWN_MAP, NOT_IN_LOOP, arity);
|
| + // Note: these flags won't let us get maps from stubs with
|
| + // non-default extra ic state in the megamorphic case. In the more
|
| + // important monomorphic case the map is obtained directly, so it's
|
| + // not a problem until we decide to emit more polymorphic code.
|
| + Code::Flags flags = Code::ComputeMonomorphicFlags(Code::CALL_IC,
|
| + NORMAL,
|
| + Code::kNoExtraICState,
|
| + OWN_MAP,
|
| + NOT_IN_LOOP,
|
| + arity);
|
| return CollectReceiverTypes(expr->position(), name, flags);
|
| }
|
|
|
|
|
| +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);
|
| }
|
|
|
|
|
| -TypeInfo TypeFeedbackOracle::CompareType(CompareOperation* expr, Side side) {
|
| +TypeInfo TypeFeedbackOracle::CompareType(CompareOperation* expr) {
|
| Handle<Object> object = GetElement(map_, expr->position());
|
| TypeInfo unknown = TypeInfo::Unknown();
|
| if (!object->IsCode()) return unknown;
|
| @@ -159,7 +198,7 @@
|
| }
|
|
|
|
|
| -TypeInfo TypeFeedbackOracle::BinaryType(BinaryOperation* expr, Side side) {
|
| +TypeInfo TypeFeedbackOracle::BinaryType(BinaryOperation* expr) {
|
| Handle<Object> object = GetElement(map_, expr->position());
|
| TypeInfo unknown = TypeInfo::Unknown();
|
| if (!object->IsCode()) return unknown;
|
| @@ -220,6 +259,7 @@
|
| return unknown;
|
| }
|
|
|
| +
|
| TypeInfo TypeFeedbackOracle::SwitchType(CaseClause* clause) {
|
| Handle<Object> object = GetElement(map_, clause->position());
|
| TypeInfo unknown = TypeInfo::Unknown();
|
| @@ -247,12 +287,11 @@
|
| }
|
|
|
|
|
| -
|
| 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 +340,20 @@
|
| 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 +390,6 @@
|
| } 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(
|
|
|