Index: src/hydrogen.cc |
diff --git a/src/hydrogen.cc b/src/hydrogen.cc |
index 8ce614fd660484efbc59f05e954b078d30acd6a9..eef6863270975b421b3cc7cd953a8037fc4aa0b4 100644 |
--- a/src/hydrogen.cc |
+++ b/src/hydrogen.cc |
@@ -4996,13 +4996,15 @@ void HOptimizedGraphBuilder::VisitRegExpLiteral(RegExpLiteral* expr) { |
} |
-static bool CanInlinePropertyAccess(Type* type) { |
+static bool CanInlinePropertyAccess(Type* type, PropertyAccessType access) { |
if (type->Is(Type::NumberOrString())) return true; |
if (!type->IsClass()) return false; |
Handle<Map> map = type->AsClass(); |
return map->IsJSObjectMap() && |
!map->is_dictionary_map() && |
- !map->has_named_interceptor(); |
+ !map->has_named_interceptor() && |
+ // Must be a LOAD or a non-observed STORE |
+ (access == LOAD || !map->is_observed()); |
} |
@@ -5414,7 +5416,7 @@ HInstruction* HOptimizedGraphBuilder::BuildStoreNamedField( |
bool HOptimizedGraphBuilder::PropertyAccessInfo::IsCompatible( |
PropertyAccessInfo* info) { |
- if (!CanInlinePropertyAccess(type_)) return false; |
+ if (!CanInlinePropertyAccess(type_, access_type_)) return false; |
// Currently only handle Type::Number as a polymorphic case. |
// TODO(verwaest): Support monomorphic handling of numbers with a HCheckNumber |
@@ -5515,7 +5517,7 @@ bool HOptimizedGraphBuilder::PropertyAccessInfo::LookupInPrototypes() { |
JSObject::TryMigrateInstance(holder_); |
} |
map = Handle<Map>(holder_->map()); |
- if (!CanInlinePropertyAccess(ToType(map))) { |
+ if (!CanInlinePropertyAccess(ToType(map), access_type_)) { |
lookup_.NotFound(); |
return false; |
} |
@@ -5528,7 +5530,7 @@ bool HOptimizedGraphBuilder::PropertyAccessInfo::LookupInPrototypes() { |
bool HOptimizedGraphBuilder::PropertyAccessInfo::CanAccessMonomorphic() { |
- if (!CanInlinePropertyAccess(type_)) return false; |
+ if (!CanInlinePropertyAccess(type_, access_type_)) return false; |
if (IsJSObjectFieldAccessor()) return IsLoad(); |
if (!LookupDescriptor()) return false; |
if (lookup_.IsFound()) { |
@@ -5807,17 +5809,27 @@ void HOptimizedGraphBuilder::HandlePolymorphicNamedFieldAccess( |
static bool ComputeReceiverTypes(Expression* expr, |
HValue* receiver, |
SmallMapList** t, |
+ PropertyAccessType access_type, |
Zone* zone) { |
SmallMapList* types = expr->GetReceiverTypes(); |
*t = types; |
bool monomorphic = expr->IsMonomorphic(); |
- if (types != NULL && receiver->HasMonomorphicJSObjectType()) { |
- Map* root_map = receiver->GetMonomorphicJSObjectMap()->FindRootMap(); |
- types->FilterForPossibleTransitions(root_map); |
+ Isolate* isolate = zone->isolate(); |
+ if (types != NULL) { |
+ if (receiver->HasMonomorphicJSObjectType()) { |
+ Map* root_map = receiver->GetMonomorphicJSObjectMap()->FindRootMap(); |
+ types->FilterForPossibleTransitions(root_map); |
+ } else if (types->is_empty() && |
+ receiver->IsConstant() && |
+ HConstant::cast(receiver)->handle(isolate)->IsJSObject()) { |
+ Handle<Map> map(Handle<JSObject>::cast( |
+ HConstant::cast(receiver)->handle(isolate))->map()); |
+ types->Add(map, zone); |
+ } |
monomorphic = types->length() == 1; |
} |
return monomorphic && CanInlinePropertyAccess( |
- IC::MapToType<Type>(types->first(), zone)); |
+ IC::MapToType<Type>(types->first(), zone), access_type); |
} |
@@ -6520,7 +6532,11 @@ HValue* HOptimizedGraphBuilder::HandleKeyedElementAccess( |
HInstruction* instr = NULL; |
SmallMapList* types; |
- bool monomorphic = ComputeReceiverTypes(expr, obj, &types, zone()); |
+ bool monomorphic = ComputeReceiverTypes(expr, |
+ obj, |
+ &types, |
+ access_type, |
+ zone()); |
bool force_generic = false; |
if (access_type == STORE && |
@@ -6659,7 +6675,7 @@ HInstruction* HOptimizedGraphBuilder::BuildNamedAccess( |
HValue* value, |
bool is_uninitialized) { |
SmallMapList* types; |
- ComputeReceiverTypes(expr, object, &types, zone()); |
+ ComputeReceiverTypes(expr, object, &types, access, zone()); |
ASSERT(types != NULL); |
if (types->length() > 0) { |
@@ -7975,7 +7991,7 @@ void HOptimizedGraphBuilder::VisitCall(Call* expr) { |
HValue* receiver = Top(); |
SmallMapList* types; |
- ComputeReceiverTypes(expr, receiver, &types, zone()); |
+ ComputeReceiverTypes(expr, receiver, &types, LOAD, zone()); |
if (prop->key()->IsPropertyName() && types->length() > 0) { |
Handle<String> name = prop->key()->AsLiteral()->AsPropertyName(); |