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

Side by Side Diff: src/hydrogen.cc

Issue 398053002: Introduce FLAG_vector_ics. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: REBASE. Created 6 years, 5 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') | src/hydrogen-instructions.h » ('j') | 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 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/hydrogen.h" 5 #include "src/hydrogen.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 8
9 #include "src/v8.h" 9 #include "src/v8.h"
10 10
(...skipping 5353 matching lines...) Expand 10 before | Expand all | Expand 10 after
5364 return ast_context()->ReturnInstruction(instr, expr->id()); 5364 return ast_context()->ReturnInstruction(instr, expr->id());
5365 } 5365 }
5366 } else { 5366 } else {
5367 HValue* global_object = Add<HLoadNamedField>( 5367 HValue* global_object = Add<HLoadNamedField>(
5368 context(), static_cast<HValue*>(NULL), 5368 context(), static_cast<HValue*>(NULL),
5369 HObjectAccess::ForContextSlot(Context::GLOBAL_OBJECT_INDEX)); 5369 HObjectAccess::ForContextSlot(Context::GLOBAL_OBJECT_INDEX));
5370 HLoadGlobalGeneric* instr = 5370 HLoadGlobalGeneric* instr =
5371 New<HLoadGlobalGeneric>(global_object, 5371 New<HLoadGlobalGeneric>(global_object,
5372 variable->name(), 5372 variable->name(),
5373 ast_context()->is_for_typeof()); 5373 ast_context()->is_for_typeof());
5374 if (FLAG_vector_ics) {
5375 Handle<SharedFunctionInfo> current_shared =
5376 function_state()->compilation_info()->shared_info();
5377 instr->SetVectorAndSlot(
5378 handle(current_shared->feedback_vector(), isolate()),
5379 expr->VariableFeedbackSlot());
5380 }
5374 return ast_context()->ReturnInstruction(instr, expr->id()); 5381 return ast_context()->ReturnInstruction(instr, expr->id());
5375 } 5382 }
5376 } 5383 }
5377 5384
5378 case Variable::PARAMETER: 5385 case Variable::PARAMETER:
5379 case Variable::LOCAL: { 5386 case Variable::LOCAL: {
5380 HValue* value = LookupAndMakeLive(variable); 5387 HValue* value = LookupAndMakeLive(variable);
5381 if (value == graph()->GetConstantHole()) { 5388 if (value == graph()->GetConstantHole()) {
5382 ASSERT(IsDeclaredVariableMode(variable->mode()) && 5389 ASSERT(IsDeclaredVariableMode(variable->mode()) &&
5383 variable->mode() != VAR); 5390 variable->mode() != VAR);
(...skipping 198 matching lines...) Expand 10 before | Expand all | Expand 10 after
5582 if (key->value()->IsInternalizedString()) { 5589 if (key->value()->IsInternalizedString()) {
5583 if (property->emit_store()) { 5590 if (property->emit_store()) {
5584 CHECK_ALIVE(VisitForValue(value)); 5591 CHECK_ALIVE(VisitForValue(value));
5585 HValue* value = Pop(); 5592 HValue* value = Pop();
5586 Handle<Map> map = property->GetReceiverType(); 5593 Handle<Map> map = property->GetReceiverType();
5587 Handle<String> name = property->key()->AsPropertyName(); 5594 Handle<String> name = property->key()->AsPropertyName();
5588 HInstruction* store; 5595 HInstruction* store;
5589 if (map.is_null()) { 5596 if (map.is_null()) {
5590 // If we don't know the monomorphic type, do a generic store. 5597 // If we don't know the monomorphic type, do a generic store.
5591 CHECK_ALIVE(store = BuildNamedGeneric( 5598 CHECK_ALIVE(store = BuildNamedGeneric(
5592 STORE, literal, name, value)); 5599 STORE, NULL, literal, name, value));
5593 } else { 5600 } else {
5594 PropertyAccessInfo info(this, STORE, ToType(map), name); 5601 PropertyAccessInfo info(this, STORE, ToType(map), name);
5595 if (info.CanAccessMonomorphic()) { 5602 if (info.CanAccessMonomorphic()) {
5596 HValue* checked_literal = Add<HCheckMaps>(literal, map); 5603 HValue* checked_literal = Add<HCheckMaps>(literal, map);
5597 ASSERT(!info.lookup()->IsPropertyCallbacks()); 5604 ASSERT(!info.lookup()->IsPropertyCallbacks());
5598 store = BuildMonomorphicAccess( 5605 store = BuildMonomorphicAccess(
5599 &info, literal, checked_literal, value, 5606 &info, literal, checked_literal, value,
5600 BailoutId::None(), BailoutId::None()); 5607 BailoutId::None(), BailoutId::None());
5601 } else { 5608 } else {
5602 CHECK_ALIVE(store = BuildNamedGeneric( 5609 CHECK_ALIVE(store = BuildNamedGeneric(
5603 STORE, literal, name, value)); 5610 STORE, NULL, literal, name, value));
5604 } 5611 }
5605 } 5612 }
5606 AddInstruction(store); 5613 AddInstruction(store);
5607 if (store->HasObservableSideEffects()) { 5614 if (store->HasObservableSideEffects()) {
5608 Add<HSimulate>(key->id(), REMOVABLE_SIMULATE); 5615 Add<HSimulate>(key->id(), REMOVABLE_SIMULATE);
5609 } 5616 }
5610 } else { 5617 } else {
5611 CHECK_ALIVE(VisitForEffect(value)); 5618 CHECK_ALIVE(VisitForEffect(value));
5612 } 5619 }
5613 break; 5620 break;
(...skipping 592 matching lines...) Expand 10 before | Expand all | Expand 10 after
6206 if (info->IsLoad()) { 6213 if (info->IsLoad()) {
6207 return New<HConstant>(info->constant()); 6214 return New<HConstant>(info->constant());
6208 } else { 6215 } else {
6209 return New<HCheckValue>(value, Handle<JSFunction>::cast(info->constant())); 6216 return New<HCheckValue>(value, Handle<JSFunction>::cast(info->constant()));
6210 } 6217 }
6211 } 6218 }
6212 6219
6213 6220
6214 void HOptimizedGraphBuilder::HandlePolymorphicNamedFieldAccess( 6221 void HOptimizedGraphBuilder::HandlePolymorphicNamedFieldAccess(
6215 PropertyAccessType access_type, 6222 PropertyAccessType access_type,
6223 Expression* expr,
6216 BailoutId ast_id, 6224 BailoutId ast_id,
6217 BailoutId return_id, 6225 BailoutId return_id,
6218 HValue* object, 6226 HValue* object,
6219 HValue* value, 6227 HValue* value,
6220 SmallMapList* types, 6228 SmallMapList* types,
6221 Handle<String> name) { 6229 Handle<String> name) {
6222 // Something did not match; must use a polymorphic load. 6230 // Something did not match; must use a polymorphic load.
6223 int count = 0; 6231 int count = 0;
6224 HBasicBlock* join = NULL; 6232 HBasicBlock* join = NULL;
6225 HBasicBlock* number_block = NULL; 6233 HBasicBlock* number_block = NULL;
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after
6319 if (current_block() != NULL) Goto(join); 6327 if (current_block() != NULL) Goto(join);
6320 set_current_block(if_false); 6328 set_current_block(if_false);
6321 } 6329 }
6322 6330
6323 // Finish up. Unconditionally deoptimize if we've handled all the maps we 6331 // Finish up. Unconditionally deoptimize if we've handled all the maps we
6324 // know about and do not want to handle ones we've never seen. Otherwise 6332 // know about and do not want to handle ones we've never seen. Otherwise
6325 // use a generic IC. 6333 // use a generic IC.
6326 if (count == types->length() && FLAG_deoptimize_uncommon_cases) { 6334 if (count == types->length() && FLAG_deoptimize_uncommon_cases) {
6327 FinishExitWithHardDeoptimization("Uknown map in polymorphic access"); 6335 FinishExitWithHardDeoptimization("Uknown map in polymorphic access");
6328 } else { 6336 } else {
6329 HInstruction* instr = BuildNamedGeneric(access_type, object, name, value); 6337 HInstruction* instr = BuildNamedGeneric(access_type, expr, object, name,
6338 value);
6330 AddInstruction(instr); 6339 AddInstruction(instr);
6331 if (!ast_context()->IsEffect()) Push(access_type == LOAD ? instr : value); 6340 if (!ast_context()->IsEffect()) Push(access_type == LOAD ? instr : value);
6332 6341
6333 if (join != NULL) { 6342 if (join != NULL) {
6334 Goto(join); 6343 Goto(join);
6335 } else { 6344 } else {
6336 Add<HSimulate>(ast_id, REMOVABLE_SIMULATE); 6345 Add<HSimulate>(ast_id, REMOVABLE_SIMULATE);
6337 if (!ast_context()->IsEffect()) ast_context()->ReturnValue(Pop()); 6346 if (!ast_context()->IsEffect()) ast_context()->ReturnValue(Pop());
6338 return; 6347 return;
6339 } 6348 }
(...skipping 426 matching lines...) Expand 10 before | Expand all | Expand 10 after
6766 return Add<HConstant>(c_string->StringValue()->length()); 6775 return Add<HConstant>(c_string->StringValue()->length());
6767 } 6776 }
6768 } 6777 }
6769 return Add<HLoadNamedField>(string, static_cast<HValue*>(NULL), 6778 return Add<HLoadNamedField>(string, static_cast<HValue*>(NULL),
6770 HObjectAccess::ForStringLength()); 6779 HObjectAccess::ForStringLength());
6771 } 6780 }
6772 6781
6773 6782
6774 HInstruction* HOptimizedGraphBuilder::BuildNamedGeneric( 6783 HInstruction* HOptimizedGraphBuilder::BuildNamedGeneric(
6775 PropertyAccessType access_type, 6784 PropertyAccessType access_type,
6785 Expression* expr,
6776 HValue* object, 6786 HValue* object,
6777 Handle<String> name, 6787 Handle<String> name,
6778 HValue* value, 6788 HValue* value,
6779 bool is_uninitialized) { 6789 bool is_uninitialized) {
6780 if (is_uninitialized) { 6790 if (is_uninitialized) {
6781 Add<HDeoptimize>("Insufficient type feedback for generic named access", 6791 Add<HDeoptimize>("Insufficient type feedback for generic named access",
6782 Deoptimizer::SOFT); 6792 Deoptimizer::SOFT);
6783 } 6793 }
6784 if (access_type == LOAD) { 6794 if (access_type == LOAD) {
6785 return New<HLoadNamedGeneric>(object, name); 6795 HLoadNamedGeneric* result = New<HLoadNamedGeneric>(object, name);
6796 if (FLAG_vector_ics) {
6797 Handle<SharedFunctionInfo> current_shared =
6798 function_state()->compilation_info()->shared_info();
6799 result->SetVectorAndSlot(
6800 handle(current_shared->feedback_vector(), isolate()),
6801 expr->AsProperty()->PropertyFeedbackSlot());
6802 }
6803 return result;
6786 } else { 6804 } else {
6787 return New<HStoreNamedGeneric>(object, name, value, function_strict_mode()); 6805 return New<HStoreNamedGeneric>(object, name, value, function_strict_mode());
6788 } 6806 }
6789 } 6807 }
6790 6808
6791 6809
6792 6810
6793 HInstruction* HOptimizedGraphBuilder::BuildKeyedGeneric( 6811 HInstruction* HOptimizedGraphBuilder::BuildKeyedGeneric(
6794 PropertyAccessType access_type, 6812 PropertyAccessType access_type,
6813 Expression* expr,
6795 HValue* object, 6814 HValue* object,
6796 HValue* key, 6815 HValue* key,
6797 HValue* value) { 6816 HValue* value) {
6798 if (access_type == LOAD) { 6817 if (access_type == LOAD) {
6799 return New<HLoadKeyedGeneric>(object, key); 6818 HLoadKeyedGeneric* result = New<HLoadKeyedGeneric>(object, key);
6819 if (FLAG_vector_ics) {
6820 Handle<SharedFunctionInfo> current_shared =
6821 function_state()->compilation_info()->shared_info();
6822 result->SetVectorAndSlot(
6823 handle(current_shared->feedback_vector(), isolate()),
6824 expr->AsProperty()->PropertyFeedbackSlot());
6825 }
6826 return result;
6800 } else { 6827 } else {
6801 return New<HStoreKeyedGeneric>(object, key, value, function_strict_mode()); 6828 return New<HStoreKeyedGeneric>(object, key, value, function_strict_mode());
6802 } 6829 }
6803 } 6830 }
6804 6831
6805 6832
6806 LoadKeyedHoleMode HOptimizedGraphBuilder::BuildKeyedHoleMode(Handle<Map> map) { 6833 LoadKeyedHoleMode HOptimizedGraphBuilder::BuildKeyedHoleMode(Handle<Map> map) {
6807 // Loads from a "stock" fast holey double arrays can elide the hole check. 6834 // Loads from a "stock" fast holey double arrays can elide the hole check.
6808 LoadKeyedHoleMode load_mode = NEVER_RETURN_HOLE; 6835 LoadKeyedHoleMode load_mode = NEVER_RETURN_HOLE;
6809 if (*map == isolate()->get_initial_js_array_map(FAST_HOLEY_DOUBLE_ELEMENTS) && 6836 if (*map == isolate()->get_initial_js_array_map(FAST_HOLEY_DOUBLE_ELEMENTS) &&
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after
6917 HInstruction* instr = BuildUncheckedMonomorphicElementAccess( 6944 HInstruction* instr = BuildUncheckedMonomorphicElementAccess(
6918 checked_object, key, val, 6945 checked_object, key, val,
6919 most_general_consolidated_map->instance_type() == JS_ARRAY_TYPE, 6946 most_general_consolidated_map->instance_type() == JS_ARRAY_TYPE,
6920 consolidated_elements_kind, 6947 consolidated_elements_kind,
6921 LOAD, NEVER_RETURN_HOLE, STANDARD_STORE); 6948 LOAD, NEVER_RETURN_HOLE, STANDARD_STORE);
6922 return instr; 6949 return instr;
6923 } 6950 }
6924 6951
6925 6952
6926 HValue* HOptimizedGraphBuilder::HandlePolymorphicElementAccess( 6953 HValue* HOptimizedGraphBuilder::HandlePolymorphicElementAccess(
6954 Expression* expr,
6927 HValue* object, 6955 HValue* object,
6928 HValue* key, 6956 HValue* key,
6929 HValue* val, 6957 HValue* val,
6930 SmallMapList* maps, 6958 SmallMapList* maps,
6931 PropertyAccessType access_type, 6959 PropertyAccessType access_type,
6932 KeyedAccessStoreMode store_mode, 6960 KeyedAccessStoreMode store_mode,
6933 bool* has_side_effects) { 6961 bool* has_side_effects) {
6934 *has_side_effects = false; 6962 *has_side_effects = false;
6935 BuildCheckHeapObject(object); 6963 BuildCheckHeapObject(object);
6936 6964
(...skipping 11 matching lines...) Expand all
6948 // Collect possible transition targets. 6976 // Collect possible transition targets.
6949 MapHandleList possible_transitioned_maps(maps->length()); 6977 MapHandleList possible_transitioned_maps(maps->length());
6950 for (int i = 0; i < maps->length(); ++i) { 6978 for (int i = 0; i < maps->length(); ++i) {
6951 Handle<Map> map = maps->at(i); 6979 Handle<Map> map = maps->at(i);
6952 ElementsKind elements_kind = map->elements_kind(); 6980 ElementsKind elements_kind = map->elements_kind();
6953 if (IsFastElementsKind(elements_kind) && 6981 if (IsFastElementsKind(elements_kind) &&
6954 elements_kind != GetInitialFastElementsKind()) { 6982 elements_kind != GetInitialFastElementsKind()) {
6955 possible_transitioned_maps.Add(map); 6983 possible_transitioned_maps.Add(map);
6956 } 6984 }
6957 if (elements_kind == SLOPPY_ARGUMENTS_ELEMENTS) { 6985 if (elements_kind == SLOPPY_ARGUMENTS_ELEMENTS) {
6958 HInstruction* result = BuildKeyedGeneric(access_type, object, key, val); 6986 HInstruction* result = BuildKeyedGeneric(access_type, expr, object, key,
6987 val);
6959 *has_side_effects = result->HasObservableSideEffects(); 6988 *has_side_effects = result->HasObservableSideEffects();
6960 return AddInstruction(result); 6989 return AddInstruction(result);
6961 } 6990 }
6962 } 6991 }
6963 // Get transition target for each map (NULL == no transition). 6992 // Get transition target for each map (NULL == no transition).
6964 for (int i = 0; i < maps->length(); ++i) { 6993 for (int i = 0; i < maps->length(); ++i) {
6965 Handle<Map> map = maps->at(i); 6994 Handle<Map> map = maps->at(i);
6966 Handle<Map> transitioned_map = 6995 Handle<Map> transitioned_map =
6967 map->FindTransitionedMap(&possible_transitioned_maps); 6996 map->FindTransitionedMap(&possible_transitioned_maps);
6968 transition_target.Add(transitioned_map); 6997 transition_target.Add(transitioned_map);
(...skipping 16 matching lines...) Expand all
6985 } 7014 }
6986 7015
6987 // If only one map is left after transitioning, handle this case 7016 // If only one map is left after transitioning, handle this case
6988 // monomorphically. 7017 // monomorphically.
6989 ASSERT(untransitionable_maps.length() >= 1); 7018 ASSERT(untransitionable_maps.length() >= 1);
6990 if (untransitionable_maps.length() == 1) { 7019 if (untransitionable_maps.length() == 1) {
6991 Handle<Map> untransitionable_map = untransitionable_maps[0]; 7020 Handle<Map> untransitionable_map = untransitionable_maps[0];
6992 HInstruction* instr = NULL; 7021 HInstruction* instr = NULL;
6993 if (untransitionable_map->has_slow_elements_kind() || 7022 if (untransitionable_map->has_slow_elements_kind() ||
6994 !untransitionable_map->IsJSObjectMap()) { 7023 !untransitionable_map->IsJSObjectMap()) {
6995 instr = AddInstruction(BuildKeyedGeneric(access_type, object, key, val)); 7024 instr = AddInstruction(BuildKeyedGeneric(access_type, expr, object, key,
7025 val));
6996 } else { 7026 } else {
6997 instr = BuildMonomorphicElementAccess( 7027 instr = BuildMonomorphicElementAccess(
6998 object, key, val, transition, untransitionable_map, access_type, 7028 object, key, val, transition, untransitionable_map, access_type,
6999 store_mode); 7029 store_mode);
7000 } 7030 }
7001 *has_side_effects |= instr->HasObservableSideEffects(); 7031 *has_side_effects |= instr->HasObservableSideEffects();
7002 return access_type == STORE ? NULL : instr; 7032 return access_type == STORE ? NULL : instr;
7003 } 7033 }
7004 7034
7005 HBasicBlock* join = graph()->CreateBasicBlock(); 7035 HBasicBlock* join = graph()->CreateBasicBlock();
7006 7036
7007 for (int i = 0; i < untransitionable_maps.length(); ++i) { 7037 for (int i = 0; i < untransitionable_maps.length(); ++i) {
7008 Handle<Map> map = untransitionable_maps[i]; 7038 Handle<Map> map = untransitionable_maps[i];
7009 if (!map->IsJSObjectMap()) continue; 7039 if (!map->IsJSObjectMap()) continue;
7010 ElementsKind elements_kind = map->elements_kind(); 7040 ElementsKind elements_kind = map->elements_kind();
7011 HBasicBlock* this_map = graph()->CreateBasicBlock(); 7041 HBasicBlock* this_map = graph()->CreateBasicBlock();
7012 HBasicBlock* other_map = graph()->CreateBasicBlock(); 7042 HBasicBlock* other_map = graph()->CreateBasicBlock();
7013 HCompareMap* mapcompare = 7043 HCompareMap* mapcompare =
7014 New<HCompareMap>(object, map, this_map, other_map); 7044 New<HCompareMap>(object, map, this_map, other_map);
7015 FinishCurrentBlock(mapcompare); 7045 FinishCurrentBlock(mapcompare);
7016 7046
7017 set_current_block(this_map); 7047 set_current_block(this_map);
7018 HInstruction* access = NULL; 7048 HInstruction* access = NULL;
7019 if (IsDictionaryElementsKind(elements_kind)) { 7049 if (IsDictionaryElementsKind(elements_kind)) {
7020 access = AddInstruction(BuildKeyedGeneric(access_type, object, key, val)); 7050 access = AddInstruction(BuildKeyedGeneric(access_type, expr, object, key,
7051 val));
7021 } else { 7052 } else {
7022 ASSERT(IsFastElementsKind(elements_kind) || 7053 ASSERT(IsFastElementsKind(elements_kind) ||
7023 IsExternalArrayElementsKind(elements_kind) || 7054 IsExternalArrayElementsKind(elements_kind) ||
7024 IsFixedTypedArrayElementsKind(elements_kind)); 7055 IsFixedTypedArrayElementsKind(elements_kind));
7025 LoadKeyedHoleMode load_mode = BuildKeyedHoleMode(map); 7056 LoadKeyedHoleMode load_mode = BuildKeyedHoleMode(map);
7026 // Happily, mapcompare is a checked object. 7057 // Happily, mapcompare is a checked object.
7027 access = BuildUncheckedMonomorphicElementAccess( 7058 access = BuildUncheckedMonomorphicElementAccess(
7028 mapcompare, key, val, 7059 mapcompare, key, val,
7029 map->instance_type() == JS_ARRAY_TYPE, 7060 map->instance_type() == JS_ARRAY_TYPE,
7030 elements_kind, access_type, 7061 elements_kind, access_type,
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
7081 force_generic = true; 7112 force_generic = true;
7082 monomorphic = false; 7113 monomorphic = false;
7083 break; 7114 break;
7084 } 7115 }
7085 } 7116 }
7086 } 7117 }
7087 7118
7088 if (monomorphic) { 7119 if (monomorphic) {
7089 Handle<Map> map = types->first(); 7120 Handle<Map> map = types->first();
7090 if (map->has_slow_elements_kind() || !map->IsJSObjectMap()) { 7121 if (map->has_slow_elements_kind() || !map->IsJSObjectMap()) {
7091 instr = AddInstruction(BuildKeyedGeneric(access_type, obj, key, val)); 7122 instr = AddInstruction(BuildKeyedGeneric(access_type, expr, obj, key,
7123 val));
7092 } else { 7124 } else {
7093 BuildCheckHeapObject(obj); 7125 BuildCheckHeapObject(obj);
7094 instr = BuildMonomorphicElementAccess( 7126 instr = BuildMonomorphicElementAccess(
7095 obj, key, val, NULL, map, access_type, expr->GetStoreMode()); 7127 obj, key, val, NULL, map, access_type, expr->GetStoreMode());
7096 } 7128 }
7097 } else if (!force_generic && (types != NULL && !types->is_empty())) { 7129 } else if (!force_generic && (types != NULL && !types->is_empty())) {
7098 return HandlePolymorphicElementAccess( 7130 return HandlePolymorphicElementAccess(
7099 obj, key, val, types, access_type, 7131 expr, obj, key, val, types, access_type,
7100 expr->GetStoreMode(), has_side_effects); 7132 expr->GetStoreMode(), has_side_effects);
7101 } else { 7133 } else {
7102 if (access_type == STORE) { 7134 if (access_type == STORE) {
7103 if (expr->IsAssignment() && 7135 if (expr->IsAssignment() &&
7104 expr->AsAssignment()->HasNoTypeInformation()) { 7136 expr->AsAssignment()->HasNoTypeInformation()) {
7105 Add<HDeoptimize>("Insufficient type feedback for keyed store", 7137 Add<HDeoptimize>("Insufficient type feedback for keyed store",
7106 Deoptimizer::SOFT); 7138 Deoptimizer::SOFT);
7107 } 7139 }
7108 } else { 7140 } else {
7109 if (expr->AsProperty()->HasNoTypeInformation()) { 7141 if (expr->AsProperty()->HasNoTypeInformation()) {
7110 Add<HDeoptimize>("Insufficient type feedback for keyed load", 7142 Add<HDeoptimize>("Insufficient type feedback for keyed load",
7111 Deoptimizer::SOFT); 7143 Deoptimizer::SOFT);
7112 } 7144 }
7113 } 7145 }
7114 instr = AddInstruction(BuildKeyedGeneric(access_type, obj, key, val)); 7146 instr = AddInstruction(BuildKeyedGeneric(access_type, expr, obj, key, val));
7115 } 7147 }
7116 *has_side_effects = instr->HasObservableSideEffects(); 7148 *has_side_effects = instr->HasObservableSideEffects();
7117 return instr; 7149 return instr;
7118 } 7150 }
7119 7151
7120 7152
7121 void HOptimizedGraphBuilder::EnsureArgumentsArePushedForAccess() { 7153 void HOptimizedGraphBuilder::EnsureArgumentsArePushedForAccess() {
7122 // Outermost function already has arguments on the stack. 7154 // Outermost function already has arguments on the stack.
7123 if (function_state()->outer() == NULL) return; 7155 if (function_state()->outer() == NULL) return;
7124 7156
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
7205 HValue* value, 7237 HValue* value,
7206 bool is_uninitialized) { 7238 bool is_uninitialized) {
7207 SmallMapList* types; 7239 SmallMapList* types;
7208 ComputeReceiverTypes(expr, object, &types, zone()); 7240 ComputeReceiverTypes(expr, object, &types, zone());
7209 ASSERT(types != NULL); 7241 ASSERT(types != NULL);
7210 7242
7211 if (types->length() > 0) { 7243 if (types->length() > 0) {
7212 PropertyAccessInfo info(this, access, ToType(types->first()), name); 7244 PropertyAccessInfo info(this, access, ToType(types->first()), name);
7213 if (!info.CanAccessAsMonomorphic(types)) { 7245 if (!info.CanAccessAsMonomorphic(types)) {
7214 HandlePolymorphicNamedFieldAccess( 7246 HandlePolymorphicNamedFieldAccess(
7215 access, ast_id, return_id, object, value, types, name); 7247 access, expr, ast_id, return_id, object, value, types, name);
7216 return NULL; 7248 return NULL;
7217 } 7249 }
7218 7250
7219 HValue* checked_object; 7251 HValue* checked_object;
7220 // Type::Number() is only supported by polymorphic load/call handling. 7252 // Type::Number() is only supported by polymorphic load/call handling.
7221 ASSERT(!info.type()->Is(Type::Number())); 7253 ASSERT(!info.type()->Is(Type::Number()));
7222 BuildCheckHeapObject(object); 7254 BuildCheckHeapObject(object);
7223 if (AreStringTypes(types)) { 7255 if (AreStringTypes(types)) {
7224 checked_object = 7256 checked_object =
7225 Add<HCheckInstanceType>(object, HCheckInstanceType::IS_STRING); 7257 Add<HCheckInstanceType>(object, HCheckInstanceType::IS_STRING);
7226 } else { 7258 } else {
7227 checked_object = Add<HCheckMaps>(object, types); 7259 checked_object = Add<HCheckMaps>(object, types);
7228 } 7260 }
7229 return BuildMonomorphicAccess( 7261 return BuildMonomorphicAccess(
7230 &info, object, checked_object, value, ast_id, return_id); 7262 &info, object, checked_object, value, ast_id, return_id);
7231 } 7263 }
7232 7264
7233 return BuildNamedGeneric(access, object, name, value, is_uninitialized); 7265 return BuildNamedGeneric(access, expr, object, name, value, is_uninitialized);
7234 } 7266 }
7235 7267
7236 7268
7237 void HOptimizedGraphBuilder::PushLoad(Property* expr, 7269 void HOptimizedGraphBuilder::PushLoad(Property* expr,
7238 HValue* object, 7270 HValue* object,
7239 HValue* key) { 7271 HValue* key) {
7240 ValueContext for_value(this, ARGUMENTS_NOT_ALLOWED); 7272 ValueContext for_value(this, ARGUMENTS_NOT_ALLOWED);
7241 Push(object); 7273 Push(object);
7242 if (key != NULL) Push(key); 7274 if (key != NULL) Push(key);
7243 BuildLoad(expr, expr->LoadId()); 7275 BuildLoad(expr, expr->LoadId());
(...skipping 308 matching lines...) Expand 10 before | Expand all | Expand 10 after
7552 } 7584 }
7553 7585
7554 // Finish up. Unconditionally deoptimize if we've handled all the maps we 7586 // Finish up. Unconditionally deoptimize if we've handled all the maps we
7555 // know about and do not want to handle ones we've never seen. Otherwise 7587 // know about and do not want to handle ones we've never seen. Otherwise
7556 // use a generic IC. 7588 // use a generic IC.
7557 if (ordered_functions == types->length() && FLAG_deoptimize_uncommon_cases) { 7589 if (ordered_functions == types->length() && FLAG_deoptimize_uncommon_cases) {
7558 FinishExitWithHardDeoptimization("Unknown map in polymorphic call"); 7590 FinishExitWithHardDeoptimization("Unknown map in polymorphic call");
7559 } else { 7591 } else {
7560 Property* prop = expr->expression()->AsProperty(); 7592 Property* prop = expr->expression()->AsProperty();
7561 HInstruction* function = BuildNamedGeneric( 7593 HInstruction* function = BuildNamedGeneric(
7562 LOAD, receiver, name, NULL, prop->IsUninitialized()); 7594 LOAD, prop, receiver, name, NULL, prop->IsUninitialized());
7563 AddInstruction(function); 7595 AddInstruction(function);
7564 Push(function); 7596 Push(function);
7565 AddSimulate(prop->LoadId(), REMOVABLE_SIMULATE); 7597 AddSimulate(prop->LoadId(), REMOVABLE_SIMULATE);
7566 7598
7567 environment()->SetExpressionStackAt(1, function); 7599 environment()->SetExpressionStackAt(1, function);
7568 environment()->SetExpressionStackAt(0, receiver); 7600 environment()->SetExpressionStackAt(0, receiver);
7569 CHECK_ALIVE(VisitExpressions(expr->arguments())); 7601 CHECK_ALIVE(VisitExpressions(expr->arguments()));
7570 7602
7571 CallFunctionFlags flags = receiver->type().IsJSObject() 7603 CallFunctionFlags flags = receiver->type().IsJSObject()
7572 ? NO_CALL_FUNCTION_FLAGS : CALL_AS_METHOD; 7604 ? NO_CALL_FUNCTION_FLAGS : CALL_AS_METHOD;
(...skipping 4865 matching lines...) Expand 10 before | Expand all | Expand 10 after
12438 if (ShouldProduceTraceOutput()) { 12470 if (ShouldProduceTraceOutput()) {
12439 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); 12471 isolate()->GetHTracer()->TraceHydrogen(name(), graph_);
12440 } 12472 }
12441 12473
12442 #ifdef DEBUG 12474 #ifdef DEBUG
12443 graph_->Verify(false); // No full verify. 12475 graph_->Verify(false); // No full verify.
12444 #endif 12476 #endif
12445 } 12477 }
12446 12478
12447 } } // namespace v8::internal 12479 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/hydrogen.h ('k') | src/hydrogen-instructions.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698