| Index: src/hydrogen.cc
|
| diff --git a/src/hydrogen.cc b/src/hydrogen.cc
|
| index c8fbbc7c87c1b6ed86de444588a196f8a280d05a..84d0c7c11033b9216338c26b84d7e20637bd049a 100644
|
| --- a/src/hydrogen.cc
|
| +++ b/src/hydrogen.cc
|
| @@ -4472,11 +4472,6 @@ void HOptimizedGraphBuilder::SetUpScope(Scope* scope) {
|
| }
|
|
|
|
|
| -Type* HOptimizedGraphBuilder::ToType(Handle<Map> map) {
|
| - return IC::MapToType<Type>(map, zone());
|
| -}
|
| -
|
| -
|
| void HOptimizedGraphBuilder::VisitStatements(ZoneList<Statement*>* statements) {
|
| for (int i = 0; i < statements->length(); i++) {
|
| Statement* stmt = statements->at(i);
|
| @@ -5445,10 +5440,9 @@ void HOptimizedGraphBuilder::VisitRegExpLiteral(RegExpLiteral* expr) {
|
| }
|
|
|
|
|
| -static bool CanInlinePropertyAccess(Type* type) {
|
| - if (type->Is(Type::NumberOrString())) return true;
|
| - if (!type->IsClass()) return false;
|
| - Handle<Map> map = type->AsClass()->Map();
|
| +static bool CanInlinePropertyAccess(Handle<Map> map) {
|
| + if (map->instance_type() == HEAP_NUMBER_TYPE) return true;
|
| + if (map->instance_type() < FIRST_NONSTRING_TYPE) return true;
|
| return map->IsJSObjectMap() &&
|
| !map->is_dictionary_map() &&
|
| !map->has_named_interceptor();
|
| @@ -5618,7 +5612,7 @@ void HOptimizedGraphBuilder::VisitObjectLiteral(ObjectLiteral* expr) {
|
| CHECK_ALIVE(store = BuildNamedGeneric(
|
| STORE, NULL, literal, name, value));
|
| } else {
|
| - PropertyAccessInfo info(this, STORE, ToType(map), name);
|
| + PropertyAccessInfo info(this, STORE, map, name);
|
| if (info.CanAccessMonomorphic()) {
|
| HValue* checked_literal = Add<HCheckMaps>(literal, map);
|
| DCHECK(!info.IsAccessorConstant());
|
| @@ -5907,20 +5901,16 @@ HInstruction* HOptimizedGraphBuilder::BuildStoreNamedField(
|
|
|
| bool HOptimizedGraphBuilder::PropertyAccessInfo::IsCompatible(
|
| PropertyAccessInfo* info) {
|
| - if (!CanInlinePropertyAccess(type_)) return false;
|
| + if (!CanInlinePropertyAccess(map_)) return false;
|
|
|
| // Currently only handle Type::Number as a polymorphic case.
|
| // TODO(verwaest): Support monomorphic handling of numbers with a HCheckNumber
|
| // instruction.
|
| - if (type_->Is(Type::Number())) return false;
|
| + if (IsNumberType()) return false;
|
|
|
| // Values are only compatible for monomorphic load if they all behave the same
|
| // regarding value wrappers.
|
| - if (type_->Is(Type::NumberOrString())) {
|
| - if (!info->type_->Is(Type::NumberOrString())) return false;
|
| - } else {
|
| - if (info->type_->Is(Type::NumberOrString())) return false;
|
| - }
|
| + if (IsValueWrapped() != info->IsValueWrapped()) return false;
|
|
|
| if (!LookupDescriptor()) return false;
|
|
|
| @@ -5979,9 +5969,9 @@ bool HOptimizedGraphBuilder::PropertyAccessInfo::IsCompatible(
|
|
|
|
|
| bool HOptimizedGraphBuilder::PropertyAccessInfo::LookupDescriptor() {
|
| - if (!type_->IsClass()) return true;
|
| - map()->LookupDescriptor(NULL, *name_, &lookup_);
|
| - return LoadResult(map());
|
| + if (!map_->IsJSObjectMap()) return true;
|
| + map_->LookupDescriptor(NULL, *name_, &lookup_);
|
| + return LoadResult(map_);
|
| }
|
|
|
|
|
| @@ -6009,9 +5999,8 @@ bool HOptimizedGraphBuilder::PropertyAccessInfo::LoadResult(Handle<Map> map) {
|
| CallOptimization call_optimization(accessor);
|
| if (call_optimization.is_simple_api_call()) {
|
| CallOptimization::HolderLookup holder_lookup;
|
| - Handle<Map> receiver_map = this->map();
|
| - api_holder_ = call_optimization.LookupHolderOfExpectedType(
|
| - receiver_map, &holder_lookup);
|
| + api_holder_ =
|
| + call_optimization.LookupHolderOfExpectedType(map_, &holder_lookup);
|
| }
|
| }
|
| accessor_ = accessor;
|
| @@ -6069,7 +6058,7 @@ bool HOptimizedGraphBuilder::PropertyAccessInfo::LookupInPrototypes() {
|
| JSObject::TryMigrateInstance(holder_);
|
| }
|
| map = Handle<Map>(holder_->map());
|
| - if (!CanInlinePropertyAccess(ToType(map))) {
|
| + if (!CanInlinePropertyAccess(map)) {
|
| lookup_.NotFound();
|
| return false;
|
| }
|
| @@ -6082,10 +6071,9 @@ bool HOptimizedGraphBuilder::PropertyAccessInfo::LookupInPrototypes() {
|
|
|
|
|
| bool HOptimizedGraphBuilder::PropertyAccessInfo::CanAccessMonomorphic() {
|
| - if (!CanInlinePropertyAccess(type_)) return false;
|
| + if (!CanInlinePropertyAccess(map_)) return false;
|
| if (IsJSObjectFieldAccessor()) return IsLoad();
|
| - if (this->map()->function_with_prototype() &&
|
| - !this->map()->has_non_instance_prototype() &&
|
| + if (map_->function_with_prototype() && !map_->has_non_instance_prototype() &&
|
| name_.is_identical_to(isolate()->factory()->prototype_string())) {
|
| return IsLoad();
|
| }
|
| @@ -6095,18 +6083,17 @@ bool HOptimizedGraphBuilder::PropertyAccessInfo::CanAccessMonomorphic() {
|
| if (IsLoad()) return true;
|
|
|
| if (IsAccessorConstant()) return true;
|
| - Handle<Map> map = this->map();
|
| - map->LookupTransition(NULL, *name_, NONE, &lookup_);
|
| - if (lookup_.IsTransitionToData() && map->unused_property_fields() > 0) {
|
| + map_->LookupTransition(NULL, *name_, NONE, &lookup_);
|
| + if (lookup_.IsTransitionToData() && map_->unused_property_fields() > 0) {
|
| // Construct the object field access.
|
| int descriptor = transition()->LastAdded();
|
| int index =
|
| transition()->instance_descriptors()->GetFieldIndex(descriptor) -
|
| - map->inobject_properties();
|
| + map_->inobject_properties();
|
| PropertyDetails details =
|
| transition()->instance_descriptors()->GetDetails(descriptor);
|
| Representation representation = details.representation();
|
| - access_ = HObjectAccess::ForField(map, index, representation, name_);
|
| + access_ = HObjectAccess::ForField(map_, index, representation, name_);
|
|
|
| // Load field map for heap objects.
|
| LoadFieldMaps(transition());
|
| @@ -6117,17 +6104,16 @@ bool HOptimizedGraphBuilder::PropertyAccessInfo::CanAccessMonomorphic() {
|
|
|
|
|
| bool HOptimizedGraphBuilder::PropertyAccessInfo::CanAccessAsMonomorphic(
|
| - SmallMapList* types) {
|
| - DCHECK(type_->Is(ToType(types->first())));
|
| + SmallMapList* maps) {
|
| + DCHECK(map_.is_identical_to(maps->first()));
|
| if (!CanAccessMonomorphic()) return false;
|
| STATIC_ASSERT(kMaxLoadPolymorphism == kMaxStorePolymorphism);
|
| - if (types->length() > kMaxLoadPolymorphism) return false;
|
| + if (maps->length() > kMaxLoadPolymorphism) return false;
|
|
|
| HObjectAccess access = HObjectAccess::ForMap(); // bogus default
|
| if (GetJSObjectFieldAccess(&access)) {
|
| - for (int i = 1; i < types->length(); ++i) {
|
| - PropertyAccessInfo test_info(
|
| - builder_, access_type_, ToType(types->at(i)), name_);
|
| + for (int i = 1; i < maps->length(); ++i) {
|
| + PropertyAccessInfo test_info(builder_, access_type_, maps->at(i), name_);
|
| HObjectAccess test_access = HObjectAccess::ForMap(); // bogus default
|
| if (!test_info.GetJSObjectFieldAccess(&test_access)) return false;
|
| if (!access.Equals(test_access)) return false;
|
| @@ -6135,18 +6121,17 @@ bool HOptimizedGraphBuilder::PropertyAccessInfo::CanAccessAsMonomorphic(
|
| return true;
|
| }
|
|
|
| - // Currently only handle Type::Number as a polymorphic case.
|
| + // Currently only handle numbers as a polymorphic case.
|
| // TODO(verwaest): Support monomorphic handling of numbers with a HCheckNumber
|
| // instruction.
|
| - if (type_->Is(Type::Number())) return false;
|
| + if (IsNumberType()) return false;
|
|
|
| // Multiple maps cannot transition to the same target map.
|
| DCHECK(!IsLoad() || !IsTransition());
|
| - if (IsTransition() && types->length() > 1) return false;
|
| + if (IsTransition() && maps->length() > 1) return false;
|
|
|
| - for (int i = 1; i < types->length(); ++i) {
|
| - PropertyAccessInfo test_info(
|
| - builder_, access_type_, ToType(types->at(i)), name_);
|
| + for (int i = 1; i < maps->length(); ++i) {
|
| + PropertyAccessInfo test_info(builder_, access_type_, maps->at(i), name_);
|
| if (!test_info.IsCompatible(this)) return false;
|
| }
|
|
|
| @@ -6156,19 +6141,25 @@ bool HOptimizedGraphBuilder::PropertyAccessInfo::CanAccessAsMonomorphic(
|
|
|
| Handle<Map> HOptimizedGraphBuilder::PropertyAccessInfo::map() {
|
| JSFunction* ctor = IC::GetRootConstructor(
|
| - type_, current_info()->closure()->context()->native_context());
|
| + *map_, current_info()->closure()->context()->native_context());
|
| if (ctor != NULL) return handle(ctor->initial_map());
|
| - return type_->AsClass()->Map();
|
| + return map_;
|
| }
|
|
|
|
|
| -static bool NeedsWrappingFor(Type* type, Handle<JSFunction> target) {
|
| - return type->Is(Type::NumberOrString()) &&
|
| +static bool NeedsWrapping(Handle<Map> map, Handle<JSFunction> target) {
|
| + return !map->IsJSObjectMap() &&
|
| is_sloppy(target->shared()->language_mode()) &&
|
| !target->shared()->native();
|
| }
|
|
|
|
|
| +bool HOptimizedGraphBuilder::PropertyAccessInfo::NeedsWrappingFor(
|
| + Handle<JSFunction> target) const {
|
| + return NeedsWrapping(map_, target);
|
| +}
|
| +
|
| +
|
| HInstruction* HOptimizedGraphBuilder::BuildMonomorphicAccess(
|
| PropertyAccessInfo* info,
|
| HValue* object,
|
| @@ -6222,7 +6213,7 @@ HInstruction* HOptimizedGraphBuilder::BuildMonomorphicAccess(
|
| Push(value);
|
| }
|
|
|
| - if (NeedsWrappingFor(info->type(), info->accessor())) {
|
| + if (info->NeedsWrappingFor(info->accessor())) {
|
| HValue* function = Add<HConstant>(info->accessor());
|
| PushArgumentsFromEnvironment(argument_count);
|
| return New<HCallFunction>(function, argument_count, WRAP_AND_CALL);
|
| @@ -6248,13 +6239,8 @@ HInstruction* HOptimizedGraphBuilder::BuildMonomorphicAccess(
|
|
|
|
|
| void HOptimizedGraphBuilder::HandlePolymorphicNamedFieldAccess(
|
| - PropertyAccessType access_type,
|
| - Expression* expr,
|
| - BailoutId ast_id,
|
| - BailoutId return_id,
|
| - HValue* object,
|
| - HValue* value,
|
| - SmallMapList* types,
|
| + PropertyAccessType access_type, Expression* expr, BailoutId ast_id,
|
| + BailoutId return_id, HValue* object, HValue* value, SmallMapList* maps,
|
| Handle<String> name) {
|
| // Something did not match; must use a polymorphic load.
|
| int count = 0;
|
| @@ -6265,33 +6251,33 @@ void HOptimizedGraphBuilder::HandlePolymorphicNamedFieldAccess(
|
| bool handle_smi = false;
|
| STATIC_ASSERT(kMaxLoadPolymorphism == kMaxStorePolymorphism);
|
| int i;
|
| - for (i = 0; i < types->length() && count < kMaxLoadPolymorphism; ++i) {
|
| - PropertyAccessInfo info(this, access_type, ToType(types->at(i)), name);
|
| - if (info.type()->Is(Type::String())) {
|
| + for (i = 0; i < maps->length() && count < kMaxLoadPolymorphism; ++i) {
|
| + PropertyAccessInfo info(this, access_type, maps->at(i), name);
|
| + if (info.IsStringType()) {
|
| if (handled_string) continue;
|
| handled_string = true;
|
| }
|
| if (info.CanAccessMonomorphic()) {
|
| count++;
|
| - if (info.type()->Is(Type::Number())) {
|
| + if (info.IsNumberType()) {
|
| handle_smi = true;
|
| break;
|
| }
|
| }
|
| }
|
|
|
| - if (i < types->length()) {
|
| + if (i < maps->length()) {
|
| count = -1;
|
| - types->Clear();
|
| + maps->Clear();
|
| } else {
|
| count = 0;
|
| }
|
| HControlInstruction* smi_check = NULL;
|
| handled_string = false;
|
|
|
| - for (i = 0; i < types->length() && count < kMaxLoadPolymorphism; ++i) {
|
| - PropertyAccessInfo info(this, access_type, ToType(types->at(i)), name);
|
| - if (info.type()->Is(Type::String())) {
|
| + for (i = 0; i < maps->length() && count < kMaxLoadPolymorphism; ++i) {
|
| + PropertyAccessInfo info(this, access_type, maps->at(i), name);
|
| + if (info.IsStringType()) {
|
| if (handled_string) continue;
|
| handled_string = true;
|
| }
|
| @@ -6318,11 +6304,11 @@ void HOptimizedGraphBuilder::HandlePolymorphicNamedFieldAccess(
|
| HUnaryControlInstruction* compare;
|
|
|
| HValue* dependency;
|
| - if (info.type()->Is(Type::Number())) {
|
| + if (info.IsNumberType()) {
|
| Handle<Map> heap_number_map = isolate()->factory()->heap_number_map();
|
| compare = New<HCompareMap>(object, heap_number_map, if_true, if_false);
|
| dependency = smi_check;
|
| - } else if (info.type()->Is(Type::String())) {
|
| + } else if (info.IsStringType()) {
|
| compare = New<HIsStringAndBranch>(object, if_true, if_false);
|
| dependency = compare;
|
| } else {
|
| @@ -6331,7 +6317,7 @@ void HOptimizedGraphBuilder::HandlePolymorphicNamedFieldAccess(
|
| }
|
| FinishCurrentBlock(compare);
|
|
|
| - if (info.type()->Is(Type::Number())) {
|
| + if (info.IsNumberType()) {
|
| GotoNoSimulate(if_true, number_block);
|
| if_true = number_block;
|
| }
|
| @@ -6366,7 +6352,7 @@ void HOptimizedGraphBuilder::HandlePolymorphicNamedFieldAccess(
|
| // Finish up. Unconditionally deoptimize if we've handled all the maps we
|
| // know about and do not want to handle ones we've never seen. Otherwise
|
| // use a generic IC.
|
| - if (count == types->length() && FLAG_deoptimize_uncommon_cases) {
|
| + if (count == maps->length() && FLAG_deoptimize_uncommon_cases) {
|
| FinishExitWithHardDeoptimization(
|
| Deoptimizer::kUnknownMapInPolymorphicAccess);
|
| } else {
|
| @@ -6399,22 +6385,21 @@ static bool ComputeReceiverTypes(Expression* expr,
|
| HValue* receiver,
|
| SmallMapList** t,
|
| Zone* zone) {
|
| - SmallMapList* types = expr->GetReceiverTypes();
|
| - *t = types;
|
| + SmallMapList* maps = expr->GetReceiverTypes();
|
| + *t = maps;
|
| bool monomorphic = expr->IsMonomorphic();
|
| - if (types != NULL && receiver->HasMonomorphicJSObjectType()) {
|
| + if (maps != NULL && receiver->HasMonomorphicJSObjectType()) {
|
| Map* root_map = receiver->GetMonomorphicJSObjectMap()->FindRootMap();
|
| - types->FilterForPossibleTransitions(root_map);
|
| - monomorphic = types->length() == 1;
|
| + maps->FilterForPossibleTransitions(root_map);
|
| + monomorphic = maps->length() == 1;
|
| }
|
| - return monomorphic &&
|
| - CanInlinePropertyAccess(IC::MapToType<Type>(types->first(), zone));
|
| + return monomorphic && CanInlinePropertyAccess(maps->first());
|
| }
|
|
|
|
|
| -static bool AreStringTypes(SmallMapList* types) {
|
| - for (int i = 0; i < types->length(); i++) {
|
| - if (types->at(i)->instance_type() >= FIRST_NONSTRING_TYPE) return false;
|
| +static bool AreStringTypes(SmallMapList* maps) {
|
| + for (int i = 0; i < maps->length(); i++) {
|
| + if (maps->at(i)->instance_type() >= FIRST_NONSTRING_TYPE) return false;
|
| }
|
| return true;
|
| }
|
| @@ -7191,8 +7176,8 @@ HValue* HOptimizedGraphBuilder::HandleKeyedElementAccess(
|
| DCHECK(!expr->IsPropertyName());
|
| HInstruction* instr = NULL;
|
|
|
| - SmallMapList* types;
|
| - bool monomorphic = ComputeReceiverTypes(expr, obj, &types, zone());
|
| + SmallMapList* maps;
|
| + bool monomorphic = ComputeReceiverTypes(expr, obj, &maps, zone());
|
|
|
| bool force_generic = false;
|
| if (expr->GetKeyType() == PROPERTY) {
|
| @@ -7202,13 +7187,13 @@ HValue* HOptimizedGraphBuilder::HandleKeyedElementAccess(
|
| force_generic = true;
|
| monomorphic = false;
|
| } else if (access_type == STORE &&
|
| - (monomorphic || (types != NULL && !types->is_empty()))) {
|
| + (monomorphic || (maps != NULL && !maps->is_empty()))) {
|
| // Stores can't be mono/polymorphic if their prototype chain has dictionary
|
| // elements. However a receiver map that has dictionary elements itself
|
| // should be left to normal mono/poly behavior (the other maps may benefit
|
| // from highly optimized stores).
|
| - for (int i = 0; i < types->length(); i++) {
|
| - Handle<Map> current_map = types->at(i);
|
| + for (int i = 0; i < maps->length(); i++) {
|
| + Handle<Map> current_map = maps->at(i);
|
| if (current_map->DictionaryElementsInPrototypeChainOnly()) {
|
| force_generic = true;
|
| monomorphic = false;
|
| @@ -7216,13 +7201,13 @@ HValue* HOptimizedGraphBuilder::HandleKeyedElementAccess(
|
| }
|
| }
|
| } else if (access_type == LOAD && !monomorphic &&
|
| - (types != NULL && !types->is_empty())) {
|
| + (maps != NULL && !maps->is_empty())) {
|
| // Polymorphic loads have to go generic if any of the maps are strings.
|
| // If some, but not all of the maps are strings, we should go generic
|
| // because polymorphic access wants to key on ElementsKind and isn't
|
| // compatible with strings.
|
| - for (int i = 0; i < types->length(); i++) {
|
| - Handle<Map> current_map = types->at(i);
|
| + for (int i = 0; i < maps->length(); i++) {
|
| + Handle<Map> current_map = maps->at(i);
|
| if (current_map->IsStringMap()) {
|
| force_generic = true;
|
| break;
|
| @@ -7231,7 +7216,7 @@ HValue* HOptimizedGraphBuilder::HandleKeyedElementAccess(
|
| }
|
|
|
| if (monomorphic) {
|
| - Handle<Map> map = types->first();
|
| + Handle<Map> map = maps->first();
|
| if (!CanInlineElementAccess(map)) {
|
| instr = AddInstruction(BuildKeyedGeneric(access_type, expr, obj, key,
|
| val));
|
| @@ -7240,10 +7225,10 @@ HValue* HOptimizedGraphBuilder::HandleKeyedElementAccess(
|
| instr = BuildMonomorphicElementAccess(
|
| obj, key, val, NULL, map, access_type, expr->GetStoreMode());
|
| }
|
| - } else if (!force_generic && (types != NULL && !types->is_empty())) {
|
| - return HandlePolymorphicElementAccess(
|
| - expr, obj, key, val, types, access_type,
|
| - expr->GetStoreMode(), has_side_effects);
|
| + } else if (!force_generic && (maps != NULL && !maps->is_empty())) {
|
| + return HandlePolymorphicElementAccess(expr, obj, key, val, maps,
|
| + access_type, expr->GetStoreMode(),
|
| + has_side_effects);
|
| } else {
|
| if (access_type == STORE) {
|
| if (expr->IsAssignment() &&
|
| @@ -7352,27 +7337,27 @@ HInstruction* HOptimizedGraphBuilder::BuildNamedAccess(
|
| Handle<String> name,
|
| HValue* value,
|
| bool is_uninitialized) {
|
| - SmallMapList* types;
|
| - ComputeReceiverTypes(expr, object, &types, zone());
|
| - DCHECK(types != NULL);
|
| -
|
| - if (types->length() > 0) {
|
| - PropertyAccessInfo info(this, access, ToType(types->first()), name);
|
| - if (!info.CanAccessAsMonomorphic(types)) {
|
| - HandlePolymorphicNamedFieldAccess(
|
| - access, expr, ast_id, return_id, object, value, types, name);
|
| + SmallMapList* maps;
|
| + ComputeReceiverTypes(expr, object, &maps, zone());
|
| + DCHECK(maps != NULL);
|
| +
|
| + if (maps->length() > 0) {
|
| + PropertyAccessInfo info(this, access, maps->first(), name);
|
| + if (!info.CanAccessAsMonomorphic(maps)) {
|
| + HandlePolymorphicNamedFieldAccess(access, expr, ast_id, return_id, object,
|
| + value, maps, name);
|
| return NULL;
|
| }
|
|
|
| HValue* checked_object;
|
| // Type::Number() is only supported by polymorphic load/call handling.
|
| - DCHECK(!info.type()->Is(Type::Number()));
|
| + DCHECK(!info.IsNumberType());
|
| BuildCheckHeapObject(object);
|
| - if (AreStringTypes(types)) {
|
| + if (AreStringTypes(maps)) {
|
| checked_object =
|
| Add<HCheckInstanceType>(object, HCheckInstanceType::IS_STRING);
|
| } else {
|
| - checked_object = Add<HCheckMaps>(object, types);
|
| + checked_object = Add<HCheckMaps>(object, maps);
|
| }
|
| return BuildMonomorphicAccess(
|
| &info, object, checked_object, value, ast_id, return_id);
|
| @@ -7562,11 +7547,10 @@ inline bool operator<(const FunctionSorter& lhs, const FunctionSorter& rhs) {
|
| }
|
|
|
|
|
| -void HOptimizedGraphBuilder::HandlePolymorphicCallNamed(
|
| - Call* expr,
|
| - HValue* receiver,
|
| - SmallMapList* types,
|
| - Handle<String> name) {
|
| +void HOptimizedGraphBuilder::HandlePolymorphicCallNamed(Call* expr,
|
| + HValue* receiver,
|
| + SmallMapList* maps,
|
| + Handle<String> name) {
|
| int argument_count = expr->arguments()->length() + 1; // Includes receiver.
|
| FunctionSorter order[kMaxCallPolymorphism];
|
|
|
| @@ -7575,17 +7559,17 @@ void HOptimizedGraphBuilder::HandlePolymorphicCallNamed(
|
| int ordered_functions = 0;
|
|
|
| int i;
|
| - for (i = 0; i < types->length() && ordered_functions < kMaxCallPolymorphism;
|
| + for (i = 0; i < maps->length() && ordered_functions < kMaxCallPolymorphism;
|
| ++i) {
|
| - PropertyAccessInfo info(this, LOAD, ToType(types->at(i)), name);
|
| + PropertyAccessInfo info(this, LOAD, maps->at(i), name);
|
| if (info.CanAccessMonomorphic() && info.IsDataConstant() &&
|
| info.constant()->IsJSFunction()) {
|
| - if (info.type()->Is(Type::String())) {
|
| + if (info.IsStringType()) {
|
| if (handled_string) continue;
|
| handled_string = true;
|
| }
|
| Handle<JSFunction> target = Handle<JSFunction>::cast(info.constant());
|
| - if (info.type()->Is(Type::Number())) {
|
| + if (info.IsNumberType()) {
|
| handle_smi = true;
|
| }
|
| expr->set_target(target);
|
| @@ -7596,8 +7580,8 @@ void HOptimizedGraphBuilder::HandlePolymorphicCallNamed(
|
|
|
| std::sort(order, order + ordered_functions);
|
|
|
| - if (i < types->length()) {
|
| - types->Clear();
|
| + if (i < maps->length()) {
|
| + maps->Clear();
|
| ordered_functions = -1;
|
| }
|
|
|
| @@ -7608,8 +7592,8 @@ void HOptimizedGraphBuilder::HandlePolymorphicCallNamed(
|
|
|
| for (int fn = 0; fn < ordered_functions; ++fn) {
|
| int i = order[fn].index();
|
| - PropertyAccessInfo info(this, LOAD, ToType(types->at(i)), name);
|
| - if (info.type()->Is(Type::String())) {
|
| + PropertyAccessInfo info(this, LOAD, maps->at(i), name);
|
| + if (info.IsStringType()) {
|
| if (handled_string) continue;
|
| handled_string = true;
|
| }
|
| @@ -7639,17 +7623,17 @@ void HOptimizedGraphBuilder::HandlePolymorphicCallNamed(
|
| HUnaryControlInstruction* compare;
|
|
|
| Handle<Map> map = info.map();
|
| - if (info.type()->Is(Type::Number())) {
|
| + if (info.IsNumberType()) {
|
| Handle<Map> heap_number_map = isolate()->factory()->heap_number_map();
|
| compare = New<HCompareMap>(receiver, heap_number_map, if_true, if_false);
|
| - } else if (info.type()->Is(Type::String())) {
|
| + } else if (info.IsStringType()) {
|
| compare = New<HIsStringAndBranch>(receiver, if_true, if_false);
|
| } else {
|
| compare = New<HCompareMap>(receiver, map, if_true, if_false);
|
| }
|
| FinishCurrentBlock(compare);
|
|
|
| - if (info.type()->Is(Type::Number())) {
|
| + if (info.IsNumberType()) {
|
| GotoNoSimulate(if_true, number_block);
|
| if_true = number_block;
|
| }
|
| @@ -7662,7 +7646,7 @@ void HOptimizedGraphBuilder::HandlePolymorphicCallNamed(
|
| environment()->SetExpressionStackAt(0, function);
|
| Push(receiver);
|
| CHECK_ALIVE(VisitExpressions(expr->arguments()));
|
| - bool needs_wrapping = NeedsWrappingFor(info.type(), target);
|
| + bool needs_wrapping = info.NeedsWrappingFor(target);
|
| bool try_inline = FLAG_polymorphic_inlining && !needs_wrapping;
|
| if (FLAG_trace_inlining && try_inline) {
|
| Handle<JSFunction> caller = current_info()->closure();
|
| @@ -7698,7 +7682,7 @@ void HOptimizedGraphBuilder::HandlePolymorphicCallNamed(
|
| // Finish up. Unconditionally deoptimize if we've handled all the maps we
|
| // know about and do not want to handle ones we've never seen. Otherwise
|
| // use a generic IC.
|
| - if (ordered_functions == types->length() && FLAG_deoptimize_uncommon_cases) {
|
| + if (ordered_functions == maps->length() && FLAG_deoptimize_uncommon_cases) {
|
| FinishExitWithHardDeoptimization(Deoptimizer::kUnknownMapInPolymorphicCall);
|
| } else {
|
| Property* prop = expr->expression()->AsProperty();
|
| @@ -9135,14 +9119,14 @@ void HOptimizedGraphBuilder::VisitCall(Call* expr) {
|
| CHECK_ALIVE(VisitForValue(prop->obj()));
|
| HValue* receiver = Top();
|
|
|
| - SmallMapList* types;
|
| - ComputeReceiverTypes(expr, receiver, &types, zone());
|
| + SmallMapList* maps;
|
| + ComputeReceiverTypes(expr, receiver, &maps, zone());
|
|
|
| - if (prop->key()->IsPropertyName() && types->length() > 0) {
|
| + if (prop->key()->IsPropertyName() && maps->length() > 0) {
|
| Handle<String> name = prop->key()->AsLiteral()->AsPropertyName();
|
| - PropertyAccessInfo info(this, LOAD, ToType(types->first()), name);
|
| - if (!info.CanAccessAsMonomorphic(types)) {
|
| - HandlePolymorphicCallNamed(expr, receiver, types, name);
|
| + PropertyAccessInfo info(this, LOAD, maps->first(), name);
|
| + if (!info.CanAccessAsMonomorphic(maps)) {
|
| + HandlePolymorphicCallNamed(expr, receiver, maps, name);
|
| return;
|
| }
|
| }
|
| @@ -9171,7 +9155,7 @@ void HOptimizedGraphBuilder::VisitCall(Call* expr) {
|
| if (TryIndirectCall(expr)) return;
|
| CHECK_ALIVE(VisitExpressions(expr->arguments()));
|
|
|
| - Handle<Map> map = types->length() == 1 ? types->first() : Handle<Map>();
|
| + Handle<Map> map = maps->length() == 1 ? maps->first() : Handle<Map>();
|
| if (TryInlineBuiltinMethodCall(expr, known_function, map,
|
| expr->arguments()->length())) {
|
| if (FLAG_trace_inlining) {
|
| @@ -9181,10 +9165,10 @@ void HOptimizedGraphBuilder::VisitCall(Call* expr) {
|
| }
|
| return;
|
| }
|
| - if (TryInlineApiMethodCall(expr, receiver, types)) return;
|
| + if (TryInlineApiMethodCall(expr, receiver, maps)) return;
|
|
|
| // Wrap the receiver if necessary.
|
| - if (NeedsWrappingFor(ToType(types->first()), known_function)) {
|
| + if (NeedsWrapping(maps->first(), known_function)) {
|
| // Since HWrapReceiver currently cannot actually wrap numbers and
|
| // strings, use the regular CallFunctionStub for method calls to wrap
|
| // the receiver.
|
|
|