Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(989)

Side by Side Diff: src/hydrogen.cc

Issue 23537024: Let BuildStore/BuildLoad distinguish between keyed/named load/stores. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Rebase Created 7 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/hydrogen.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2013 the V8 project authors. All rights reserved. 1 // Copyright 2013 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 4878 matching lines...) Expand 10 before | Expand all | Expand 10 after
4889 4889
4890 ASSERT(join != NULL); 4890 ASSERT(join != NULL);
4891 join->SetJoinId(assignment_id); 4891 join->SetJoinId(assignment_id);
4892 set_current_block(join); 4892 set_current_block(join);
4893 if (!ast_context()->IsEffect()) { 4893 if (!ast_context()->IsEffect()) {
4894 ast_context()->ReturnValue(Pop()); 4894 ast_context()->ReturnValue(Pop());
4895 } 4895 }
4896 } 4896 }
4897 4897
4898 4898
4899 void HOptimizedGraphBuilder::HandlePropertyAssignment(Assignment* expr) {
4900 Property* prop = expr->target()->AsProperty();
4901 ASSERT(prop != NULL);
4902 CHECK_ALIVE(VisitForValue(prop->obj()));
4903
4904 if (prop->key()->IsPropertyName()) {
4905 // Named store.
4906 CHECK_ALIVE(VisitForValue(expr->value()));
4907 HValue* value = environment()->ExpressionStackAt(0);
4908 HValue* object = environment()->ExpressionStackAt(1);
4909
4910 if (expr->IsUninitialized()) {
4911 Add<HDeoptimize>("Insufficient type feedback for property assignment",
4912 Deoptimizer::SOFT);
4913 }
4914 return BuildStoreNamed(
4915 expr, expr->id(), expr->AssignmentId(), prop, object, value);
4916 } else {
4917 // Keyed store.
4918 CHECK_ALIVE(VisitForValue(prop->key()));
4919 CHECK_ALIVE(VisitForValue(expr->value()));
4920 HValue* value = environment()->ExpressionStackAt(0);
4921 HValue* key = environment()->ExpressionStackAt(1);
4922 HValue* object = environment()->ExpressionStackAt(2);
4923 bool has_side_effects = false;
4924 HandleKeyedElementAccess(object, key, value, expr, expr->AssignmentId(),
4925 expr->position(),
4926 true, // is_store
4927 &has_side_effects);
4928 Drop(3);
4929 Push(value);
4930 Add<HSimulate>(expr->AssignmentId(), REMOVABLE_SIMULATE);
4931 return ast_context()->ReturnValue(Pop());
4932 }
4933 }
4934
4935
4936 // Because not every expression has a position and there is not common
4937 // superclass of Assignment and CountOperation, we cannot just pass the
4938 // owning expression instead of position and ast_id separately.
4939 void HOptimizedGraphBuilder::HandleGlobalVariableAssignment(
4940 Variable* var,
4941 HValue* value,
4942 int position,
4943 BailoutId ast_id) {
4944 LookupResult lookup(isolate());
4945 GlobalPropertyAccess type = LookupGlobalProperty(var, &lookup, true);
4946 if (type == kUseCell) {
4947 Handle<GlobalObject> global(current_info()->global_object());
4948 Handle<PropertyCell> cell(global->GetPropertyCell(&lookup));
4949 if (cell->type()->IsConstant()) {
4950 IfBuilder builder(this);
4951 HValue* constant = Add<HConstant>(cell->type()->AsConstant());
4952 if (cell->type()->AsConstant()->IsNumber()) {
4953 builder.If<HCompareNumericAndBranch>(value, constant, Token::EQ);
4954 } else {
4955 builder.If<HCompareObjectEqAndBranch>(value, constant);
4956 }
4957 builder.Then();
4958 builder.Else();
4959 Add<HDeoptimize>("Constant global variable assignment",
4960 Deoptimizer::EAGER);
4961 builder.End();
4962 }
4963 HInstruction* instr =
4964 Add<HStoreGlobalCell>(value, cell, lookup.GetPropertyDetails());
4965 instr->set_position(position);
4966 if (instr->HasObservableSideEffects()) {
4967 Add<HSimulate>(ast_id, REMOVABLE_SIMULATE);
4968 }
4969 } else {
4970 HGlobalObject* global_object = Add<HGlobalObject>();
4971 HStoreGlobalGeneric* instr =
4972 Add<HStoreGlobalGeneric>(global_object, var->name(),
4973 value, function_strict_mode_flag());
4974 instr->set_position(position);
4975 ASSERT(instr->HasObservableSideEffects());
4976 Add<HSimulate>(ast_id, REMOVABLE_SIMULATE);
4977 }
4978 }
4979
4980
4981 static bool ComputeReceiverTypes(Expression* expr, 4899 static bool ComputeReceiverTypes(Expression* expr,
4982 HValue* receiver, 4900 HValue* receiver,
4983 SmallMapList** t) { 4901 SmallMapList** t) {
4984 SmallMapList* types = expr->GetReceiverTypes(); 4902 SmallMapList* types = expr->GetReceiverTypes();
4985 *t = types; 4903 *t = types;
4986 bool monomorphic = expr->IsMonomorphic(); 4904 bool monomorphic = expr->IsMonomorphic();
4987 if (types != NULL && receiver->HasMonomorphicJSObjectType()) { 4905 if (types != NULL && receiver->HasMonomorphicJSObjectType()) {
4988 Map* root_map = receiver->GetMonomorphicJSObjectMap()->FindRootMap(); 4906 Map* root_map = receiver->GetMonomorphicJSObjectMap()->FindRootMap();
4989 types->FilterForPossibleTransitions(root_map); 4907 types->FilterForPossibleTransitions(root_map);
4990 monomorphic = types->length() == 1; 4908 monomorphic = types->length() == 1;
4991 } 4909 }
4992 return monomorphic && CanInlinePropertyAccess(*types->first()); 4910 return monomorphic && CanInlinePropertyAccess(*types->first());
4993 } 4911 }
4994 4912
4995 4913
4996 void HOptimizedGraphBuilder::BuildStoreNamed(Expression* expr, 4914 void HOptimizedGraphBuilder::BuildStore(Expression* expr,
4997 BailoutId id, 4915 Property* prop,
4998 BailoutId assignment_id, 4916 BailoutId ast_id,
4999 Property* prop, 4917 BailoutId return_id,
5000 HValue* object, 4918 bool is_uninitialized) {
5001 HValue* value) { 4919 HValue* value = environment()->ExpressionStackAt(0);
4920
4921 if (!prop->key()->IsPropertyName()) {
4922 // Keyed store.
4923 HValue* key = environment()->ExpressionStackAt(1);
4924 HValue* object = environment()->ExpressionStackAt(2);
4925 bool has_side_effects = false;
4926 HandleKeyedElementAccess(object, key, value, expr, return_id,
4927 expr->position(),
4928 true, // is_store
4929 &has_side_effects);
4930 Drop(3);
4931 Push(value);
4932 Add<HSimulate>(return_id, REMOVABLE_SIMULATE);
4933 return ast_context()->ReturnValue(Pop());
4934 }
4935
4936 // Named store.
4937 HValue* object = environment()->ExpressionStackAt(1);
4938
4939 if (is_uninitialized) {
4940 Add<HDeoptimize>("Insufficient type feedback for property assignment",
4941 Deoptimizer::SOFT);
4942 }
4943
5002 Literal* key = prop->key()->AsLiteral(); 4944 Literal* key = prop->key()->AsLiteral();
5003 Handle<String> name = Handle<String>::cast(key->value()); 4945 Handle<String> name = Handle<String>::cast(key->value());
5004 ASSERT(!name.is_null()); 4946 ASSERT(!name.is_null());
5005 4947
5006 HInstruction* instr = NULL; 4948 HInstruction* instr = NULL;
5007 4949
5008 SmallMapList* types; 4950 SmallMapList* types;
5009 bool monomorphic = ComputeReceiverTypes(expr, object, &types); 4951 bool monomorphic = ComputeReceiverTypes(expr, object, &types);
5010 4952
5011 if (monomorphic) { 4953 if (monomorphic) {
5012 Handle<Map> map = types->first(); 4954 Handle<Map> map = types->first();
5013 Handle<JSFunction> setter; 4955 Handle<JSFunction> setter;
5014 Handle<JSObject> holder; 4956 Handle<JSObject> holder;
5015 if (LookupSetter(map, name, &setter, &holder)) { 4957 if (LookupSetter(map, name, &setter, &holder)) {
5016 AddCheckConstantFunction(holder, object, map); 4958 AddCheckConstantFunction(holder, object, map);
5017 if (FLAG_inline_accessors && 4959 if (FLAG_inline_accessors &&
5018 TryInlineSetter(setter, id, assignment_id, value)) { 4960 TryInlineSetter(setter, ast_id, return_id, value)) {
5019 return; 4961 return;
5020 } 4962 }
5021 Drop(2); 4963 Drop(2);
5022 Add<HPushArgument>(object); 4964 Add<HPushArgument>(object);
5023 Add<HPushArgument>(value); 4965 Add<HPushArgument>(value);
5024 instr = new(zone()) HCallConstantFunction(setter, 2); 4966 instr = new(zone()) HCallConstantFunction(setter, 2);
5025 } else { 4967 } else {
5026 Drop(2); 4968 Drop(2);
5027 CHECK_ALIVE(instr = BuildStoreNamedMonomorphic(object, 4969 CHECK_ALIVE(instr = BuildStoreNamedMonomorphic(object,
5028 name, 4970 name,
5029 value, 4971 value,
5030 map)); 4972 map));
5031 } 4973 }
5032 } else if (types != NULL && types->length() > 1) { 4974 } else if (types != NULL && types->length() > 1) {
5033 Drop(2); 4975 Drop(2);
5034 return HandlePolymorphicStoreNamedField( 4976 return HandlePolymorphicStoreNamedField(
5035 expr->position(), id, object, value, types, name); 4977 expr->position(), ast_id, object, value, types, name);
5036 } else { 4978 } else {
5037 Drop(2); 4979 Drop(2);
5038 instr = BuildStoreNamedGeneric(object, name, value); 4980 instr = BuildStoreNamedGeneric(object, name, value);
5039 } 4981 }
5040 4982
5041 if (!ast_context()->IsEffect()) Push(value); 4983 if (!ast_context()->IsEffect()) Push(value);
5042 instr->set_position(expr->position()); 4984 instr->set_position(expr->position());
5043 AddInstruction(instr); 4985 AddInstruction(instr);
5044 if (instr->HasObservableSideEffects()) { 4986 if (instr->HasObservableSideEffects()) {
5045 Add<HSimulate>(id, REMOVABLE_SIMULATE); 4987 Add<HSimulate>(ast_id, REMOVABLE_SIMULATE);
5046 } 4988 }
5047 if (!ast_context()->IsEffect()) Drop(1); 4989 if (!ast_context()->IsEffect()) Drop(1);
5048 return ast_context()->ReturnValue(value); 4990 return ast_context()->ReturnValue(value);
5049 } 4991 }
5050 4992
5051 4993
4994 void HOptimizedGraphBuilder::HandlePropertyAssignment(Assignment* expr) {
4995 Property* prop = expr->target()->AsProperty();
4996 ASSERT(prop != NULL);
4997 CHECK_ALIVE(VisitForValue(prop->obj()));
4998 if (!prop->key()->IsPropertyName()) {
4999 CHECK_ALIVE(VisitForValue(prop->key()));
5000 }
5001 CHECK_ALIVE(VisitForValue(expr->value()));
5002 BuildStore(expr, prop, expr->id(),
5003 expr->AssignmentId(), expr->IsUninitialized());
5004 }
5005
5006
5007 // Because not every expression has a position and there is not common
5008 // superclass of Assignment and CountOperation, we cannot just pass the
5009 // owning expression instead of position and ast_id separately.
5010 void HOptimizedGraphBuilder::HandleGlobalVariableAssignment(
5011 Variable* var,
5012 HValue* value,
5013 int position,
5014 BailoutId ast_id) {
5015 LookupResult lookup(isolate());
5016 GlobalPropertyAccess type = LookupGlobalProperty(var, &lookup, true);
5017 if (type == kUseCell) {
5018 Handle<GlobalObject> global(current_info()->global_object());
5019 Handle<PropertyCell> cell(global->GetPropertyCell(&lookup));
5020 if (cell->type()->IsConstant()) {
5021 IfBuilder builder(this);
5022 HValue* constant = Add<HConstant>(cell->type()->AsConstant());
5023 if (cell->type()->AsConstant()->IsNumber()) {
5024 builder.If<HCompareNumericAndBranch>(value, constant, Token::EQ);
5025 } else {
5026 builder.If<HCompareObjectEqAndBranch>(value, constant);
5027 }
5028 builder.Then();
5029 builder.Else();
5030 Add<HDeoptimize>("Constant global variable assignment",
5031 Deoptimizer::EAGER);
5032 builder.End();
5033 }
5034 HInstruction* instr =
5035 Add<HStoreGlobalCell>(value, cell, lookup.GetPropertyDetails());
5036 instr->set_position(position);
5037 if (instr->HasObservableSideEffects()) {
5038 Add<HSimulate>(ast_id, REMOVABLE_SIMULATE);
5039 }
5040 } else {
5041 HGlobalObject* global_object = Add<HGlobalObject>();
5042 HStoreGlobalGeneric* instr =
5043 Add<HStoreGlobalGeneric>(global_object, var->name(),
5044 value, function_strict_mode_flag());
5045 instr->set_position(position);
5046 ASSERT(instr->HasObservableSideEffects());
5047 Add<HSimulate>(ast_id, REMOVABLE_SIMULATE);
5048 }
5049 }
5050
5051
5052 void HOptimizedGraphBuilder::HandleCompoundAssignment(Assignment* expr) { 5052 void HOptimizedGraphBuilder::HandleCompoundAssignment(Assignment* expr) {
5053 Expression* target = expr->target(); 5053 Expression* target = expr->target();
5054 VariableProxy* proxy = target->AsVariableProxy(); 5054 VariableProxy* proxy = target->AsVariableProxy();
5055 Property* prop = target->AsProperty(); 5055 Property* prop = target->AsProperty();
5056 ASSERT(proxy == NULL || prop == NULL); 5056 ASSERT(proxy == NULL || prop == NULL);
5057 5057
5058 // We have a second position recorded in the FullCodeGenerator to have 5058 // We have a second position recorded in the FullCodeGenerator to have
5059 // type feedback for the binary operation. 5059 // type feedback for the binary operation.
5060 BinaryOperation* operation = expr->binary_operation(); 5060 BinaryOperation* operation = expr->binary_operation();
5061 5061
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
5123 } 5123 }
5124 break; 5124 break;
5125 } 5125 }
5126 5126
5127 case Variable::LOOKUP: 5127 case Variable::LOOKUP:
5128 return Bailout(kCompoundAssignmentToLookupSlot); 5128 return Bailout(kCompoundAssignmentToLookupSlot);
5129 } 5129 }
5130 return ast_context()->ReturnValue(Pop()); 5130 return ast_context()->ReturnValue(Pop());
5131 5131
5132 } else if (prop != NULL) { 5132 } else if (prop != NULL) {
5133 if (prop->key()->IsPropertyName()) { 5133 CHECK_ALIVE(VisitForValue(prop->obj()));
5134 // Named property. 5134 HValue* object = Top();
5135 CHECK_ALIVE(VisitForValue(prop->obj())); 5135 HValue* key = NULL;
5136 HValue* object = Top(); 5136 if ((!prop->IsStringLength() &&
5137 CHECK_ALIVE(PushLoad(prop, object, expr->position())); 5137 !prop->IsFunctionPrototype() &&
5138 5138 !prop->key()->IsPropertyName()) ||
5139 CHECK_ALIVE(VisitForValue(expr->value())); 5139 prop->IsStringAccess()) {
5140 HValue* right = Pop();
5141 HValue* left = Pop();
5142
5143 HInstruction* instr = BuildBinaryOperation(operation, left, right);
5144 PushAndAdd(instr);
5145 if (instr->HasObservableSideEffects()) {
5146 Add<HSimulate>(operation->id(), REMOVABLE_SIMULATE);
5147 }
5148
5149 return BuildStoreNamed(
5150 expr, expr->id(), expr->AssignmentId(), prop, object, instr);
5151 } else {
5152 // Keyed property.
5153 CHECK_ALIVE(VisitForValue(prop->obj()));
5154 CHECK_ALIVE(VisitForValue(prop->key())); 5140 CHECK_ALIVE(VisitForValue(prop->key()));
5155 HValue* obj = environment()->ExpressionStackAt(1); 5141 key = Top();
5156 HValue* key = environment()->ExpressionStackAt(0);
5157
5158 bool has_side_effects = false;
5159 HValue* load = HandleKeyedElementAccess(
5160 obj, key, NULL, prop, prop->LoadId(), RelocInfo::kNoPosition,
5161 false, // is_store
5162 &has_side_effects);
5163 Push(load);
5164 if (has_side_effects) Add<HSimulate>(prop->LoadId(), REMOVABLE_SIMULATE);
5165
5166 CHECK_ALIVE(VisitForValue(expr->value()));
5167 HValue* right = Pop();
5168 HValue* left = Pop();
5169
5170 HInstruction* instr = BuildBinaryOperation(operation, left, right);
5171 PushAndAdd(instr);
5172 if (instr->HasObservableSideEffects()) {
5173 Add<HSimulate>(operation->id(), REMOVABLE_SIMULATE);
5174 }
5175
5176 HandleKeyedElementAccess(obj, key, instr, expr, expr->AssignmentId(),
5177 RelocInfo::kNoPosition,
5178 true, // is_store
5179 &has_side_effects);
5180
5181 // Drop the simulated receiver, key, and value. Return the value.
5182 Drop(3);
5183 Push(instr);
5184 ASSERT(has_side_effects); // Stores always have side effects.
5185 Add<HSimulate>(expr->AssignmentId(), REMOVABLE_SIMULATE);
5186 return ast_context()->ReturnValue(Pop());
5187 } 5142 }
5188 5143
5144 CHECK_ALIVE(PushLoad(prop, object, key, expr->position()));
5145
5146 CHECK_ALIVE(VisitForValue(expr->value()));
5147 HValue* right = Pop();
5148 HValue* left = Pop();
5149
5150 HInstruction* instr = BuildBinaryOperation(operation, left, right);
5151 PushAndAdd(instr);
5152 if (instr->HasObservableSideEffects()) {
5153 Add<HSimulate>(operation->id(), REMOVABLE_SIMULATE);
5154 }
5155 BuildStore(expr, prop, expr->id(),
5156 expr->AssignmentId(), expr->IsUninitialized());
5189 } else { 5157 } else {
5190 return Bailout(kInvalidLhsInCompoundAssignment); 5158 return Bailout(kInvalidLhsInCompoundAssignment);
5191 } 5159 }
5192 } 5160 }
5193 5161
5194 5162
5195 void HOptimizedGraphBuilder::VisitAssignment(Assignment* expr) { 5163 void HOptimizedGraphBuilder::VisitAssignment(Assignment* expr) {
5196 ASSERT(!HasStackOverflow()); 5164 ASSERT(!HasStackOverflow());
5197 ASSERT(current_block() != NULL); 5165 ASSERT(current_block() != NULL);
5198 ASSERT(current_block()->HasPredecessor()); 5166 ASSERT(current_block()->HasPredecessor());
(...skipping 634 matching lines...) Expand 10 before | Expand all | Expand 10 after
5833 result = new(zone()) HAccessArgumentsAt(elements, length, checked_key); 5801 result = new(zone()) HAccessArgumentsAt(elements, length, checked_key);
5834 } 5802 }
5835 } 5803 }
5836 ast_context()->ReturnInstruction(result, expr->id()); 5804 ast_context()->ReturnInstruction(result, expr->id());
5837 return true; 5805 return true;
5838 } 5806 }
5839 5807
5840 5808
5841 void HOptimizedGraphBuilder::PushLoad(Property* expr, 5809 void HOptimizedGraphBuilder::PushLoad(Property* expr,
5842 HValue* object, 5810 HValue* object,
5811 HValue* key,
5843 int position) { 5812 int position) {
5844 ValueContext for_value(this, ARGUMENTS_NOT_ALLOWED); 5813 ValueContext for_value(this, ARGUMENTS_NOT_ALLOWED);
5845 Push(object); 5814 Push(object);
5815 if (key != NULL) Push(key);
5846 BuildLoad(expr, position, expr->LoadId()); 5816 BuildLoad(expr, position, expr->LoadId());
5847 } 5817 }
5848 5818
5849 5819
5850 void HOptimizedGraphBuilder::BuildLoad(Property* expr, 5820 void HOptimizedGraphBuilder::BuildLoad(Property* expr,
5851 int position, 5821 int position,
5852 BailoutId ast_id) { 5822 BailoutId ast_id) {
5853 HInstruction* instr = NULL; 5823 HInstruction* instr = NULL;
5854 if (expr->IsStringLength()) { 5824 if (expr->IsStringLength()) {
5855 HValue* string = Pop(); 5825 HValue* string = Pop();
5856 BuildCheckHeapObject(string); 5826 BuildCheckHeapObject(string);
5857 HInstruction* checkstring = 5827 HInstruction* checkstring =
5858 AddInstruction(HCheckInstanceType::NewIsString(string, zone())); 5828 AddInstruction(HCheckInstanceType::NewIsString(string, zone()));
5859 instr = BuildLoadStringLength(string, checkstring); 5829 instr = BuildLoadStringLength(string, checkstring);
5860 } else if (expr->IsStringAccess()) { 5830 } else if (expr->IsStringAccess()) {
5861 CHECK_ALIVE(VisitForValue(expr->key()));
5862 HValue* index = Pop(); 5831 HValue* index = Pop();
5863 HValue* string = Pop(); 5832 HValue* string = Pop();
5864 HValue* context = environment()->context(); 5833 HValue* context = environment()->context();
5865 HInstruction* char_code = 5834 HInstruction* char_code =
5866 BuildStringCharCodeAt(string, index); 5835 BuildStringCharCodeAt(string, index);
5867 AddInstruction(char_code); 5836 AddInstruction(char_code);
5868 instr = HStringCharFromCode::New(zone(), context, char_code); 5837 instr = HStringCharFromCode::New(zone(), context, char_code);
5869 5838
5870 } else if (expr->IsFunctionPrototype()) { 5839 } else if (expr->IsFunctionPrototype()) {
5871 HValue* function = Pop(); 5840 HValue* function = Pop();
(...skipping 23 matching lines...) Expand all
5895 instr = BuildLoadNamedMonomorphic(Pop(), name, map); 5864 instr = BuildLoadNamedMonomorphic(Pop(), name, map);
5896 } 5865 }
5897 } else if (types != NULL && types->length() > 1) { 5866 } else if (types != NULL && types->length() > 1) {
5898 return HandlePolymorphicLoadNamedField( 5867 return HandlePolymorphicLoadNamedField(
5899 position, ast_id, Pop(), types, name); 5868 position, ast_id, Pop(), types, name);
5900 } else { 5869 } else {
5901 instr = BuildLoadNamedGeneric(Pop(), name, expr); 5870 instr = BuildLoadNamedGeneric(Pop(), name, expr);
5902 } 5871 }
5903 5872
5904 } else { 5873 } else {
5905 CHECK_ALIVE(VisitForValue(expr->key()));
5906
5907 HValue* key = Pop(); 5874 HValue* key = Pop();
5908 HValue* obj = Pop(); 5875 HValue* obj = Pop();
5909 5876
5910 bool has_side_effects = false; 5877 bool has_side_effects = false;
5911 HValue* load = HandleKeyedElementAccess( 5878 HValue* load = HandleKeyedElementAccess(
5912 obj, key, NULL, expr, ast_id, position, 5879 obj, key, NULL, expr, ast_id, position,
5913 false, // is_store 5880 false, // is_store
5914 &has_side_effects); 5881 &has_side_effects);
5915 if (has_side_effects) { 5882 if (has_side_effects) {
5916 if (ast_context()->IsEffect()) { 5883 if (ast_context()->IsEffect()) {
(...skipping 12 matching lines...) Expand all
5929 5896
5930 5897
5931 void HOptimizedGraphBuilder::VisitProperty(Property* expr) { 5898 void HOptimizedGraphBuilder::VisitProperty(Property* expr) {
5932 ASSERT(!HasStackOverflow()); 5899 ASSERT(!HasStackOverflow());
5933 ASSERT(current_block() != NULL); 5900 ASSERT(current_block() != NULL);
5934 ASSERT(current_block()->HasPredecessor()); 5901 ASSERT(current_block()->HasPredecessor());
5935 5902
5936 if (TryArgumentsAccess(expr)) return; 5903 if (TryArgumentsAccess(expr)) return;
5937 5904
5938 CHECK_ALIVE(VisitForValue(expr->obj())); 5905 CHECK_ALIVE(VisitForValue(expr->obj()));
5906 if ((!expr->IsStringLength() &&
5907 !expr->IsFunctionPrototype() &&
5908 !expr->key()->IsPropertyName()) ||
5909 expr->IsStringAccess()) {
5910 CHECK_ALIVE(VisitForValue(expr->key()));
5911 }
5912
5939 BuildLoad(expr, expr->position(), expr->id()); 5913 BuildLoad(expr, expr->position(), expr->id());
5940 } 5914 }
5941 5915
5942 5916
5943 HInstruction* HGraphBuilder::BuildConstantMapCheck(Handle<JSObject> constant, 5917 HInstruction* HGraphBuilder::BuildConstantMapCheck(Handle<JSObject> constant,
5944 CompilationInfo* info) { 5918 CompilationInfo* info) {
5945 HConstant* constant_value = New<HConstant>(constant); 5919 HConstant* constant_value = New<HConstant>(constant);
5946 5920
5947 if (constant->map()->CanOmitMapChecks()) { 5921 if (constant->map()->CanOmitMapChecks()) {
5948 constant->map()->AddDependentCompilationInfo( 5922 constant->map()->AddDependentCompilationInfo(
(...skipping 1522 matching lines...) Expand 10 before | Expand all | Expand 10 after
7471 HAdd* add = HAdd::cast(instr); 7445 HAdd* add = HAdd::cast(instr);
7472 add->set_observed_input_representation(1, rep); 7446 add->set_observed_input_representation(1, rep);
7473 add->set_observed_input_representation(2, Representation::Smi()); 7447 add->set_observed_input_representation(2, Representation::Smi());
7474 } 7448 }
7475 instr->SetFlag(HInstruction::kCannotBeTagged); 7449 instr->SetFlag(HInstruction::kCannotBeTagged);
7476 instr->ClearAllSideEffects(); 7450 instr->ClearAllSideEffects();
7477 return instr; 7451 return instr;
7478 } 7452 }
7479 7453
7480 7454
7481 void HOptimizedGraphBuilder::BuildStoreInEffect(Expression* expr, 7455 void HOptimizedGraphBuilder::BuildStoreForEffect(Expression* expr,
7482 Property* prop, 7456 Property* prop,
7483 BailoutId ast_id, 7457 BailoutId ast_id,
7484 BailoutId return_id, 7458 BailoutId return_id,
7485 HValue* object, 7459 HValue* object,
7486 HValue* value) { 7460 HValue* key,
7461 HValue* value) {
7487 EffectContext for_effect(this); 7462 EffectContext for_effect(this);
7488 Push(object); 7463 Push(object);
7464 if (key != NULL) Push(key);
7489 Push(value); 7465 Push(value);
7490 BuildStoreNamed(expr, ast_id, return_id, prop, object, value); 7466 BuildStore(expr, prop, ast_id, return_id);
7491 } 7467 }
7492 7468
7493 7469
7494 void HOptimizedGraphBuilder::VisitCountOperation(CountOperation* expr) { 7470 void HOptimizedGraphBuilder::VisitCountOperation(CountOperation* expr) {
7495 ASSERT(!HasStackOverflow()); 7471 ASSERT(!HasStackOverflow());
7496 ASSERT(current_block() != NULL); 7472 ASSERT(current_block() != NULL);
7497 ASSERT(current_block()->HasPredecessor()); 7473 ASSERT(current_block()->HasPredecessor());
7498 Expression* target = expr->expression(); 7474 Expression* target = expr->expression();
7499 VariableProxy* proxy = target->AsVariableProxy(); 7475 VariableProxy* proxy = target->AsVariableProxy();
7500 Property* prop = target->AsProperty(); 7476 Property* prop = target->AsProperty();
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
7560 if (instr->HasObservableSideEffects()) { 7536 if (instr->HasObservableSideEffects()) {
7561 Add<HSimulate>(expr->AssignmentId(), REMOVABLE_SIMULATE); 7537 Add<HSimulate>(expr->AssignmentId(), REMOVABLE_SIMULATE);
7562 } 7538 }
7563 break; 7539 break;
7564 } 7540 }
7565 7541
7566 case Variable::LOOKUP: 7542 case Variable::LOOKUP:
7567 return Bailout(kLookupVariableInCountOperation); 7543 return Bailout(kLookupVariableInCountOperation);
7568 } 7544 }
7569 7545
7570 } else { 7546 Drop(returns_original_input ? 2 : 1);
7571 // Argument of the count operation is a property. 7547 return ast_context()->ReturnValue(expr->is_postfix() ? input : after);
7572 ASSERT(prop != NULL);
7573
7574 if (prop->key()->IsPropertyName()) {
7575 // Named property.
7576 if (returns_original_input) Push(graph()->GetConstantUndefined());
7577
7578 CHECK_ALIVE(VisitForValue(prop->obj()));
7579 HValue* object = Top();
7580 CHECK_ALIVE(PushLoad(prop, object, expr->position()));
7581
7582 after = BuildIncrement(returns_original_input, expr);
7583
7584 if (returns_original_input) {
7585 HValue* result = Pop();
7586 HValue* object = Pop();
7587 environment()->SetExpressionStackAt(0, result);
7588 CHECK_ALIVE(BuildStoreInEffect(
7589 expr, prop, expr->id(), expr->AssignmentId(), object, after));
7590 return ast_context()->ReturnValue(Pop());
7591 }
7592
7593 return BuildStoreNamed(
7594 expr, expr->id(), expr->AssignmentId(), prop, object, after);
7595 } else {
7596 // Keyed property.
7597 if (returns_original_input) Push(graph()->GetConstantUndefined());
7598
7599 CHECK_ALIVE(VisitForValue(prop->obj()));
7600 CHECK_ALIVE(VisitForValue(prop->key()));
7601 HValue* obj = environment()->ExpressionStackAt(1);
7602 HValue* key = environment()->ExpressionStackAt(0);
7603
7604 bool has_side_effects = false;
7605 HValue* load = HandleKeyedElementAccess(
7606 obj, key, NULL, prop, prop->LoadId(), RelocInfo::kNoPosition,
7607 false, // is_store
7608 &has_side_effects);
7609 Push(load);
7610 if (has_side_effects) Add<HSimulate>(prop->LoadId(), REMOVABLE_SIMULATE);
7611
7612 after = BuildIncrement(returns_original_input, expr);
7613 input = environment()->ExpressionStackAt(0);
7614
7615 HandleKeyedElementAccess(obj, key, after, expr, expr->AssignmentId(),
7616 RelocInfo::kNoPosition,
7617 true, // is_store
7618 &has_side_effects);
7619
7620 // Drop the key and the original value from the bailout environment.
7621 // Overwrite the receiver with the result of the operation, and the
7622 // placeholder with the original value if necessary.
7623 Drop(2);
7624 environment()->SetExpressionStackAt(0, after);
7625 if (returns_original_input) environment()->SetExpressionStackAt(1, input);
7626 ASSERT(has_side_effects); // Stores always have side effects.
7627 Add<HSimulate>(expr->AssignmentId(), REMOVABLE_SIMULATE);
7628 }
7629 } 7548 }
7630 7549
7631 Drop(returns_original_input ? 2 : 1); 7550 // Argument of the count operation is a property.
7632 return ast_context()->ReturnValue(expr->is_postfix() ? input : after); 7551 ASSERT(prop != NULL);
7552 if (returns_original_input) Push(graph()->GetConstantUndefined());
7553
7554 CHECK_ALIVE(VisitForValue(prop->obj()));
7555 HValue* object = Top();
7556
7557 HValue* key = NULL;
7558 if ((!prop->IsStringLength() &&
7559 !prop->IsFunctionPrototype() &&
7560 !prop->key()->IsPropertyName()) ||
7561 prop->IsStringAccess()) {
7562 CHECK_ALIVE(VisitForValue(prop->key()));
7563 key = Top();
7564 }
7565
7566 CHECK_ALIVE(PushLoad(prop, object, key, expr->position()));
7567
7568 after = BuildIncrement(returns_original_input, expr);
7569
7570 if (returns_original_input) {
7571 input = Pop();
7572 // Drop object and key to push it again in the effect context below.
7573 Drop(key == NULL ? 1 : 2);
7574 environment()->SetExpressionStackAt(0, input);
7575 CHECK_ALIVE(BuildStoreForEffect(
7576 expr, prop, expr->id(), expr->AssignmentId(), object, key, after));
7577 return ast_context()->ReturnValue(Pop());
7578 }
7579
7580 environment()->SetExpressionStackAt(0, after);
7581 return BuildStore(expr, prop, expr->id(), expr->AssignmentId());
7633 } 7582 }
7634 7583
7635 7584
7636 HInstruction* HOptimizedGraphBuilder::BuildStringCharCodeAt( 7585 HInstruction* HOptimizedGraphBuilder::BuildStringCharCodeAt(
7637 HValue* string, 7586 HValue* string,
7638 HValue* index) { 7587 HValue* index) {
7639 if (string->IsConstant() && index->IsConstant()) { 7588 if (string->IsConstant() && index->IsConstant()) {
7640 HConstant* c_string = HConstant::cast(string); 7589 HConstant* c_string = HConstant::cast(string);
7641 HConstant* c_index = HConstant::cast(index); 7590 HConstant* c_index = HConstant::cast(index);
7642 if (c_string->HasStringValue() && c_index->HasNumberValue()) { 7591 if (c_string->HasStringValue() && c_index->HasNumberValue()) {
(...skipping 2083 matching lines...) Expand 10 before | Expand all | Expand 10 after
9726 if (ShouldProduceTraceOutput()) { 9675 if (ShouldProduceTraceOutput()) {
9727 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); 9676 isolate()->GetHTracer()->TraceHydrogen(name(), graph_);
9728 } 9677 }
9729 9678
9730 #ifdef DEBUG 9679 #ifdef DEBUG
9731 graph_->Verify(false); // No full verify. 9680 graph_->Verify(false); // No full verify.
9732 #endif 9681 #endif
9733 } 9682 }
9734 9683
9735 } } // namespace v8::internal 9684 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/hydrogen.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698