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

Side by Side Diff: src/hydrogen.cc

Issue 155513008: Unify BuildLoad/StoreNamedGeneric (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 6 years, 10 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 5053 matching lines...) Expand 10 before | Expand all | Expand 10 after
5064 case ObjectLiteral::Property::COMPUTED: 5064 case ObjectLiteral::Property::COMPUTED:
5065 if (key->value()->IsInternalizedString()) { 5065 if (key->value()->IsInternalizedString()) {
5066 if (property->emit_store()) { 5066 if (property->emit_store()) {
5067 CHECK_ALIVE(VisitForValue(value)); 5067 CHECK_ALIVE(VisitForValue(value));
5068 HValue* value = Pop(); 5068 HValue* value = Pop();
5069 Handle<Map> map = property->GetReceiverType(); 5069 Handle<Map> map = property->GetReceiverType();
5070 Handle<String> name = property->key()->AsPropertyName(); 5070 Handle<String> name = property->key()->AsPropertyName();
5071 HInstruction* store; 5071 HInstruction* store;
5072 if (map.is_null()) { 5072 if (map.is_null()) {
5073 // If we don't know the monomorphic type, do a generic store. 5073 // If we don't know the monomorphic type, do a generic store.
5074 CHECK_ALIVE(store = BuildStoreNamedGeneric(literal, name, value)); 5074 CHECK_ALIVE(store = BuildNamedGeneric(
5075 STORE, literal, name, value));
5075 } else { 5076 } else {
5076 PropertyAccessInfo info(this, STORE, ToType(map), name); 5077 PropertyAccessInfo info(this, STORE, ToType(map), name);
5077 if (info.CanAccessMonomorphic()) { 5078 if (info.CanAccessMonomorphic()) {
5078 HValue* checked_literal = BuildCheckMap(literal, map); 5079 HValue* checked_literal = BuildCheckMap(literal, map);
5079 ASSERT(!info.lookup()->IsPropertyCallbacks()); 5080 ASSERT(!info.lookup()->IsPropertyCallbacks());
5080 store = BuildMonomorphicAccess( 5081 store = BuildMonomorphicAccess(
5081 &info, literal, checked_literal, value, 5082 &info, literal, checked_literal, value,
5082 BailoutId::None(), BailoutId::None()); 5083 BailoutId::None(), BailoutId::None());
5083 } else { 5084 } else {
5084 CHECK_ALIVE( 5085 CHECK_ALIVE(store = BuildNamedGeneric(
5085 store = BuildStoreNamedGeneric(literal, name, value)); 5086 STORE, literal, name, value));
5086 } 5087 }
5087 } 5088 }
5088 AddInstruction(store); 5089 AddInstruction(store);
5089 if (store->HasObservableSideEffects()) { 5090 if (store->HasObservableSideEffects()) {
5090 Add<HSimulate>(key->id(), REMOVABLE_SIMULATE); 5091 Add<HSimulate>(key->id(), REMOVABLE_SIMULATE);
5091 } 5092 }
5092 } else { 5093 } else {
5093 CHECK_ALIVE(VisitForEffect(value)); 5094 CHECK_ALIVE(VisitForEffect(value));
5094 } 5095 }
5095 break; 5096 break;
(...skipping 211 matching lines...) Expand 10 before | Expand all | Expand 10 after
5307 5308
5308 if (transition_to_field) { 5309 if (transition_to_field) {
5309 HConstant* transition_constant = Add<HConstant>(info->transition()); 5310 HConstant* transition_constant = Add<HConstant>(info->transition());
5310 instr->SetTransition(transition_constant, top_info()); 5311 instr->SetTransition(transition_constant, top_info());
5311 instr->SetGVNFlag(kChangesMaps); 5312 instr->SetGVNFlag(kChangesMaps);
5312 } 5313 }
5313 return instr; 5314 return instr;
5314 } 5315 }
5315 5316
5316 5317
5317 HInstruction* HOptimizedGraphBuilder::BuildStoreNamedGeneric(
5318 HValue* object,
5319 Handle<String> name,
5320 HValue* value,
5321 bool is_uninitialized) {
5322 if (is_uninitialized) {
5323 Add<HDeoptimize>("Insufficient type feedback for property assignment",
5324 Deoptimizer::SOFT);
5325 }
5326
5327 return New<HStoreNamedGeneric>(
5328 object,
5329 name,
5330 value,
5331 function_strict_mode_flag());
5332 }
5333
5334
5335 bool HOptimizedGraphBuilder::PropertyAccessInfo::IsCompatible( 5318 bool HOptimizedGraphBuilder::PropertyAccessInfo::IsCompatible(
5336 PropertyAccessInfo* info) { 5319 PropertyAccessInfo* info) {
5337 if (!CanInlinePropertyAccess(type_)) return false; 5320 if (!CanInlinePropertyAccess(type_)) return false;
5338 5321
5339 // Currently only handle Type::Number as a polymorphic case. 5322 // Currently only handle Type::Number as a polymorphic case.
5340 // TODO(verwaest): Support monomorphic handling of numbers with a HCheckNumber 5323 // TODO(verwaest): Support monomorphic handling of numbers with a HCheckNumber
5341 // instruction. 5324 // instruction.
5342 if (type_->Is(Type::Number())) return false; 5325 if (type_->Is(Type::Number())) return false;
5343 5326
5344 // Values are only compatible for monomorphic load if they all behave the same 5327 // Values are only compatible for monomorphic load if they all behave the same
(...skipping 369 matching lines...) Expand 10 before | Expand all | Expand 10 after
5714 } 5697 }
5715 5698
5716 // Finish up. Unconditionally deoptimize if we've handled all the maps we 5699 // Finish up. Unconditionally deoptimize if we've handled all the maps we
5717 // know about and do not want to handle ones we've never seen. Otherwise 5700 // know about and do not want to handle ones we've never seen. Otherwise
5718 // use a generic IC. 5701 // use a generic IC.
5719 if (count == types->length() && FLAG_deoptimize_uncommon_cases) { 5702 if (count == types->length() && FLAG_deoptimize_uncommon_cases) {
5720 // Because the deopt may be the only path in the polymorphic load, make sure 5703 // Because the deopt may be the only path in the polymorphic load, make sure
5721 // that the environment stack matches the depth on deopt that it otherwise 5704 // that the environment stack matches the depth on deopt that it otherwise
5722 // would have had after a successful load. 5705 // would have had after a successful load.
5723 if (!ast_context()->IsEffect()) Push(graph()->GetConstant0()); 5706 if (!ast_context()->IsEffect()) Push(graph()->GetConstant0());
5724 const char* message = ""; 5707 FinishExitWithHardDeoptimization("Uknown map in polymorphic access", join);
5725 switch (access_type) {
5726 case LOAD:
5727 message = "Unknown map in polymorphic load";
5728 break;
5729 case STORE:
5730 message = "Unknown map in polymorphic store";
5731 break;
5732 }
5733 FinishExitWithHardDeoptimization(message, join);
5734 } else { 5708 } else {
5735 HValue* result = NULL; 5709 HInstruction* instr = BuildNamedGeneric(access_type, object, name, value);
5736 switch (access_type) { 5710 AddInstruction(instr);
5737 case LOAD: 5711 if (!ast_context()->IsEffect()) Push(access_type == LOAD ? instr : value);
5738 result = Add<HLoadNamedGeneric>(object, name);
5739 break;
5740 case STORE:
5741 AddInstruction(BuildStoreNamedGeneric(object, name, value));
5742 result = value;
5743 break;
5744 }
5745 if (!ast_context()->IsEffect()) Push(result);
5746 5712
5747 if (join != NULL) { 5713 if (join != NULL) {
5748 Goto(join); 5714 Goto(join);
5749 } else { 5715 } else {
5750 Add<HSimulate>(ast_id, REMOVABLE_SIMULATE); 5716 Add<HSimulate>(ast_id, REMOVABLE_SIMULATE);
5751 if (!ast_context()->IsEffect()) ast_context()->ReturnValue(Pop()); 5717 if (!ast_context()->IsEffect()) ast_context()->ReturnValue(Pop());
5752 return; 5718 return;
5753 } 5719 }
5754 } 5720 }
5755 5721
(...skipping 431 matching lines...) Expand 10 before | Expand all | Expand 10 after
6187 if (string->IsConstant()) { 6153 if (string->IsConstant()) {
6188 HConstant* c_string = HConstant::cast(string); 6154 HConstant* c_string = HConstant::cast(string);
6189 if (c_string->HasStringValue()) { 6155 if (c_string->HasStringValue()) {
6190 return Add<HConstant>(c_string->StringValue()->length()); 6156 return Add<HConstant>(c_string->StringValue()->length());
6191 } 6157 }
6192 } 6158 }
6193 return AddLoadNamedField(string, HObjectAccess::ForStringLength()); 6159 return AddLoadNamedField(string, HObjectAccess::ForStringLength());
6194 } 6160 }
6195 6161
6196 6162
6197 HInstruction* HOptimizedGraphBuilder::BuildLoadNamedGeneric( 6163 HInstruction* HOptimizedGraphBuilder::BuildNamedGeneric(
6164 PropertyAccessType access_type,
6198 HValue* object, 6165 HValue* object,
6199 Handle<String> name, 6166 Handle<String> name,
6167 HValue* value,
6200 bool is_uninitialized) { 6168 bool is_uninitialized) {
6201 if (is_uninitialized) { 6169 if (is_uninitialized) {
6202 Add<HDeoptimize>("Insufficient type feedback for generic named load", 6170 Add<HDeoptimize>("Insufficient type feedback for generic named access",
6203 Deoptimizer::SOFT); 6171 Deoptimizer::SOFT);
6204 } 6172 }
6205 return New<HLoadNamedGeneric>(object, name); 6173 if (access_type == LOAD) {
6174 return New<HLoadNamedGeneric>(object, name);
6175 } else {
6176 return New<HStoreNamedGeneric>(
6177 object, name, value, function_strict_mode_flag());
6178 }
6206 } 6179 }
6207 6180
6208 6181
6209 6182
6210 HInstruction* HOptimizedGraphBuilder::BuildLoadKeyedGeneric(HValue* object, 6183 HInstruction* HOptimizedGraphBuilder::BuildLoadKeyedGeneric(HValue* object,
6211 HValue* key) { 6184 HValue* key) {
6212 return New<HLoadKeyedGeneric>(object, key); 6185 return New<HLoadKeyedGeneric>(object, key);
6213 } 6186 }
6214 6187
6215 6188
(...skipping 425 matching lines...) Expand 10 before | Expand all | Expand 10 after
6641 if (AreStringTypes(types)) { 6614 if (AreStringTypes(types)) {
6642 checked_object = 6615 checked_object =
6643 Add<HCheckInstanceType>(object, HCheckInstanceType::IS_STRING); 6616 Add<HCheckInstanceType>(object, HCheckInstanceType::IS_STRING);
6644 } else { 6617 } else {
6645 checked_object = Add<HCheckMaps>(object, types); 6618 checked_object = Add<HCheckMaps>(object, types);
6646 } 6619 }
6647 return BuildMonomorphicAccess( 6620 return BuildMonomorphicAccess(
6648 &info, object, checked_object, value, ast_id, return_id); 6621 &info, object, checked_object, value, ast_id, return_id);
6649 } 6622 }
6650 6623
6651 if (access == LOAD) { 6624 return BuildNamedGeneric(access, object, name, value, is_uninitialized);
6652 return BuildLoadNamedGeneric(object, name, is_uninitialized);
6653 } else {
6654 return BuildStoreNamedGeneric(object, name, value, is_uninitialized);
6655 }
6656 } 6625 }
6657 6626
6658 6627
6659 void HOptimizedGraphBuilder::PushLoad(Property* expr, 6628 void HOptimizedGraphBuilder::PushLoad(Property* expr,
6660 HValue* object, 6629 HValue* object,
6661 HValue* key) { 6630 HValue* key) {
6662 ValueContext for_value(this, ARGUMENTS_NOT_ALLOWED); 6631 ValueContext for_value(this, ARGUMENTS_NOT_ALLOWED);
6663 Push(object); 6632 Push(object);
6664 if (key != NULL) Push(key); 6633 if (key != NULL) Push(key);
6665 BuildLoad(expr, expr->LoadId()); 6634 BuildLoad(expr, expr->LoadId());
(...skipping 331 matching lines...) Expand 10 before | Expand all | Expand 10 after
6997 // use a generic IC. 6966 // use a generic IC.
6998 if (ordered_functions == types->length() && FLAG_deoptimize_uncommon_cases) { 6967 if (ordered_functions == types->length() && FLAG_deoptimize_uncommon_cases) {
6999 // Because the deopt may be the only path in the polymorphic call, make sure 6968 // Because the deopt may be the only path in the polymorphic call, make sure
7000 // that the environment stack matches the depth on deopt that it otherwise 6969 // that the environment stack matches the depth on deopt that it otherwise
7001 // would have had after a successful call. 6970 // would have had after a successful call.
7002 Drop(1); // Drop receiver. 6971 Drop(1); // Drop receiver.
7003 if (!ast_context()->IsEffect()) Push(graph()->GetConstant0()); 6972 if (!ast_context()->IsEffect()) Push(graph()->GetConstant0());
7004 FinishExitWithHardDeoptimization("Unknown map in polymorphic call", join); 6973 FinishExitWithHardDeoptimization("Unknown map in polymorphic call", join);
7005 } else { 6974 } else {
7006 Property* prop = expr->expression()->AsProperty(); 6975 Property* prop = expr->expression()->AsProperty();
7007 HInstruction* function = BuildLoadNamedGeneric( 6976 HInstruction* function = BuildNamedGeneric(
7008 receiver, name, prop->IsUninitialized()); 6977 LOAD, receiver, name, NULL, prop->IsUninitialized());
7009 AddInstruction(function); 6978 AddInstruction(function);
7010 Push(function); 6979 Push(function);
7011 AddSimulate(prop->LoadId(), REMOVABLE_SIMULATE); 6980 AddSimulate(prop->LoadId(), REMOVABLE_SIMULATE);
7012 6981
7013 environment()->SetExpressionStackAt(1, function); 6982 environment()->SetExpressionStackAt(1, function);
7014 environment()->SetExpressionStackAt(0, receiver); 6983 environment()->SetExpressionStackAt(0, receiver);
7015 CHECK_ALIVE(VisitExpressions(expr->arguments())); 6984 CHECK_ALIVE(VisitExpressions(expr->arguments()));
7016 6985
7017 CallFunctionFlags flags = receiver->type().IsJSObject() 6986 CallFunctionFlags flags = receiver->type().IsJSObject()
7018 ? NO_CALL_FUNCTION_FLAGS : CALL_AS_METHOD; 6987 ? NO_CALL_FUNCTION_FLAGS : CALL_AS_METHOD;
(...skipping 4224 matching lines...) Expand 10 before | Expand all | Expand 10 after
11243 if (ShouldProduceTraceOutput()) { 11212 if (ShouldProduceTraceOutput()) {
11244 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); 11213 isolate()->GetHTracer()->TraceHydrogen(name(), graph_);
11245 } 11214 }
11246 11215
11247 #ifdef DEBUG 11216 #ifdef DEBUG
11248 graph_->Verify(false); // No full verify. 11217 graph_->Verify(false); // No full verify.
11249 #endif 11218 #endif
11250 } 11219 }
11251 11220
11252 } } // namespace v8::internal 11221 } } // 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