From: verwaest@chromium.org Date: Wed, 5 Feb 2014 15:28:57 +0000 (+0000) Subject: Merge polymorphic load/store handling X-Git-Tag: upstream/4.7.83~10866 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=cb044fa2d85270aafa699d0376e69da51cf93e1b;p=platform%2Fupstream%2Fv8.git Merge polymorphic load/store handling R=dcarney@chromium.org Review URL: https://codereview.chromium.org/150573010 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@19106 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- diff --git a/src/hydrogen.cc b/src/hydrogen.cc index 1593301..ce83d90 100644 --- a/src/hydrogen.cc +++ b/src/hydrogen.cc @@ -5610,10 +5610,12 @@ HInstruction* HOptimizedGraphBuilder::BuildStoreMonomorphic( } -void HOptimizedGraphBuilder::HandlePolymorphicLoadNamedField( +void HOptimizedGraphBuilder::HandlePolymorphicNamedFieldAccess( + PropertyAccessType access_type, BailoutId ast_id, BailoutId return_id, HValue* object, + HValue* value, SmallMapList* types, Handle name) { // Something did not match; must use a polymorphic load. @@ -5623,8 +5625,9 @@ void HOptimizedGraphBuilder::HandlePolymorphicLoadNamedField( bool handled_string = false; bool handle_smi = false; + STATIC_ASSERT(kMaxLoadPolymorphism == kMaxStorePolymorphism); for (int i = 0; i < types->length() && count < kMaxLoadPolymorphism; ++i) { - PropertyAccessInfo info(this, LOAD, ToType(types->at(i)), name); + PropertyAccessInfo info(this, access_type, ToType(types->at(i)), name); if (info.type()->Is(Type::String())) { if (handled_string) continue; handled_string = true; @@ -5643,7 +5646,7 @@ void HOptimizedGraphBuilder::HandlePolymorphicLoadNamedField( handled_string = false; for (int i = 0; i < types->length() && count < kMaxLoadPolymorphism; ++i) { - PropertyAccessInfo info(this, LOAD, ToType(types->at(i)), name); + PropertyAccessInfo info(this, access_type, ToType(types->at(i)), name); if (info.type()->Is(Type::String())) { if (handled_string) continue; handled_string = true; @@ -5692,16 +5695,28 @@ void HOptimizedGraphBuilder::HandlePolymorphicLoadNamedField( set_current_block(if_true); - HInstruction* load = BuildLoadMonomorphic( - &info, object, dependency, ast_id, - return_id, FLAG_polymorphic_inlining); - if (load == NULL) { + HInstruction* access = NULL; + HValue* result = NULL; + switch (access_type) { + case LOAD: + access = BuildLoadMonomorphic( + &info, object, dependency, ast_id, + return_id, FLAG_polymorphic_inlining); + result = access; + break; + case STORE: + access = BuildStoreMonomorphic( + &info, dependency, value, ast_id, return_id, + FLAG_polymorphic_inlining); + result = value; + break; + } + + if (access == NULL) { if (HasStackOverflow()) return; } else { - if (!load->IsLinked()) { - AddInstruction(load); - } - if (!ast_context()->IsEffect()) Push(load); + if (!access->IsLinked()) AddInstruction(access); + if (!ast_context()->IsEffect()) Push(result); } if (current_block() != NULL) Goto(join); @@ -5716,10 +5731,28 @@ void HOptimizedGraphBuilder::HandlePolymorphicLoadNamedField( // that the environment stack matches the depth on deopt that it otherwise // would have had after a successful load. if (!ast_context()->IsEffect()) Push(graph()->GetConstant0()); - FinishExitWithHardDeoptimization("Unknown map in polymorphic load", join); + const char* message = ""; + switch (access_type) { + case LOAD: + message = "Unknown map in polymorphic load"; + break; + case STORE: + message = "Unknown map in polymorphic store"; + break; + } + FinishExitWithHardDeoptimization(message, join); } else { - HInstruction* load = Add(object, name); - if (!ast_context()->IsEffect()) Push(load); + HValue* result = NULL; + switch (access_type) { + case LOAD: + result = Add(object, name); + break; + case STORE: + AddInstruction(BuildStoreNamedGeneric(object, name, value)); + result = value; + break; + } + if (!ast_context()->IsEffect()) Push(result); if (join != NULL) { Goto(join); @@ -5737,90 +5770,6 @@ void HOptimizedGraphBuilder::HandlePolymorphicLoadNamedField( } -void HOptimizedGraphBuilder::HandlePolymorphicStoreNamedField( - BailoutId assignment_id, - BailoutId return_id, - HValue* object, - HValue* value, - SmallMapList* types, - Handle name) { - int count = 0; - HBasicBlock* join = NULL; - // TODO(verwaest): Unify with polymorphic load handling. - for (int i = 0; i < types->length() && count < kMaxStorePolymorphism; ++i) { - PropertyAccessInfo info(this, STORE, ToType(types->at(i)), name); - if (info.CanAccessMonomorphic()) { - if (count == 0) { - BuildCheckHeapObject(object); - join = graph()->CreateBasicBlock(); - } - ++count; - HBasicBlock* if_true = graph()->CreateBasicBlock(); - HBasicBlock* if_false = graph()->CreateBasicBlock(); - HCompareMap* compare = New( - object, info.map(), if_true, if_false); - FinishCurrentBlock(compare); - - set_current_block(if_true); - - HInstruction* store; - store = BuildStoreMonomorphic( - &info, compare, value, assignment_id, return_id, - FLAG_polymorphic_inlining); - - if (store == NULL) { - if (HasStackOverflow()) return; - } else { - ASSERT(!store->IsLinked()); - AddInstruction(store); - if (!ast_context()->IsEffect()) Push(value); - } - - if (current_block() != NULL) Goto(join); - set_current_block(if_false); - } - } - - // 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) { - FinishExitWithHardDeoptimization("Unknown map in polymorphic store", join); - } else { - HInstruction* instr = BuildStoreNamedGeneric(object, name, value); - AddInstruction(instr); - - if (join != NULL) { - if (!ast_context()->IsEffect()) { - Push(value); - } - Goto(join); - } else { - // The HSimulate for the store should not see the stored value in - // effect contexts (it is not materialized at expr->id() in the - // unoptimized code). - if (instr->HasObservableSideEffects()) { - if (ast_context()->IsEffect()) { - Add(assignment_id, REMOVABLE_SIMULATE); - } else { - Push(value); - Add(assignment_id, REMOVABLE_SIMULATE); - Drop(1); - } - } - return ast_context()->ReturnValue(value); - } - } - - ASSERT(join != NULL); - join->SetJoinId(assignment_id); - set_current_block(join); - if (!ast_context()->IsEffect()) { - ast_context()->ReturnValue(Pop()); - } -} - - static bool ComputeReceiverTypes(Expression* expr, HValue* receiver, SmallMapList** t, @@ -5882,8 +5831,8 @@ void HOptimizedGraphBuilder::BuildStore(Expression* expr, if (types->length() > 0) { PropertyAccessInfo info(this, STORE, ToType(types->first()), name); if (!info.CanAccessAsMonomorphic(types)) { - return HandlePolymorphicStoreNamedField( - ast_id, return_id, object, value, types, name); + return HandlePolymorphicNamedFieldAccess( + STORE, ast_id, return_id, object, value, types, name); } ASSERT(!info.type()->Is(Type::Number())); @@ -6734,8 +6683,8 @@ void HOptimizedGraphBuilder::BuildLoad(Property* expr, if (types->length() > 0) { PropertyAccessInfo info(this, LOAD, ToType(types->first()), name); if (!info.CanAccessAsMonomorphic(types)) { - return HandlePolymorphicLoadNamedField( - ast_id, expr->LoadId(), object, types, name); + return HandlePolymorphicNamedFieldAccess( + LOAD, ast_id, expr->LoadId(), object, NULL, types, name); } HValue* checked_object; diff --git a/src/hydrogen.h b/src/hydrogen.h index 7eb2c84..46cfa71 100644 --- a/src/hydrogen.h +++ b/src/hydrogen.h @@ -2187,6 +2187,8 @@ class HOptimizedGraphBuilder : public HGraphBuilder, public AstVisitor { Type* ToType(Handle map) { return IC::MapToType(map, zone()); } private: + enum PropertyAccessType { LOAD, STORE }; + // Helpers for flow graph construction. enum GlobalPropertyAccess { kUseCell, @@ -2251,11 +2253,13 @@ class HOptimizedGraphBuilder : public HGraphBuilder, public AstVisitor { void HandlePropertyAssignment(Assignment* expr); void HandleCompoundAssignment(Assignment* expr); - void HandlePolymorphicLoadNamedField(BailoutId ast_id, - BailoutId return_id, - HValue* object, - SmallMapList* types, - Handle name); + void HandlePolymorphicNamedFieldAccess(PropertyAccessType access_type, + BailoutId ast_id, + BailoutId return_id, + HValue* object, + HValue* value, + SmallMapList* types, + Handle name); void VisitTypedArrayInitialize(CallRuntime* expr); @@ -2264,7 +2268,6 @@ class HOptimizedGraphBuilder : public HGraphBuilder, public AstVisitor { void VisitDataViewInitialize(CallRuntime* expr); - enum PropertyAccessType { LOAD, STORE }; class PropertyAccessInfo { public: PropertyAccessInfo(HOptimizedGraphBuilder* builder, @@ -2390,12 +2393,6 @@ class HOptimizedGraphBuilder : public HGraphBuilder, public AstVisitor { BailoutId return_id, bool can_inline_accessor = true); - void HandlePolymorphicStoreNamedField(BailoutId assignment_id, - BailoutId return_id, - HValue* object, - HValue* value, - SmallMapList* types, - Handle name); void HandlePolymorphicCallNamed(Call* expr, HValue* receiver, SmallMapList* types,