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

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: Register passed in hydrogen, fixed some test failures. 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
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 5291 matching lines...) Expand 10 before | Expand all | Expand 10 after
5302 return ast_context()->ReturnInstruction(instr, expr->id()); 5302 return ast_context()->ReturnInstruction(instr, expr->id());
5303 } 5303 }
5304 } else { 5304 } else {
5305 HValue* global_object = Add<HLoadNamedField>( 5305 HValue* global_object = Add<HLoadNamedField>(
5306 context(), static_cast<HValue*>(NULL), 5306 context(), static_cast<HValue*>(NULL),
5307 HObjectAccess::ForContextSlot(Context::GLOBAL_OBJECT_INDEX)); 5307 HObjectAccess::ForContextSlot(Context::GLOBAL_OBJECT_INDEX));
5308 HLoadGlobalGeneric* instr = 5308 HLoadGlobalGeneric* instr =
5309 New<HLoadGlobalGeneric>(global_object, 5309 New<HLoadGlobalGeneric>(global_object,
5310 variable->name(), 5310 variable->name(),
5311 ast_context()->is_for_typeof()); 5311 ast_context()->is_for_typeof());
5312 if (FLAG_vector_ics) {
5313 instr->set_slot(expr->VariableFeedbackSlot());
5314 }
5312 return ast_context()->ReturnInstruction(instr, expr->id()); 5315 return ast_context()->ReturnInstruction(instr, expr->id());
5313 } 5316 }
5314 } 5317 }
5315 5318
5316 case Variable::PARAMETER: 5319 case Variable::PARAMETER:
5317 case Variable::LOCAL: { 5320 case Variable::LOCAL: {
5318 HValue* value = LookupAndMakeLive(variable); 5321 HValue* value = LookupAndMakeLive(variable);
5319 if (value == graph()->GetConstantHole()) { 5322 if (value == graph()->GetConstantHole()) {
5320 ASSERT(IsDeclaredVariableMode(variable->mode()) && 5323 ASSERT(IsDeclaredVariableMode(variable->mode()) &&
5321 variable->mode() != VAR); 5324 variable->mode() != VAR);
(...skipping 198 matching lines...) Expand 10 before | Expand all | Expand 10 after
5520 if (key->value()->IsInternalizedString()) { 5523 if (key->value()->IsInternalizedString()) {
5521 if (property->emit_store()) { 5524 if (property->emit_store()) {
5522 CHECK_ALIVE(VisitForValue(value)); 5525 CHECK_ALIVE(VisitForValue(value));
5523 HValue* value = Pop(); 5526 HValue* value = Pop();
5524 Handle<Map> map = property->GetReceiverType(); 5527 Handle<Map> map = property->GetReceiverType();
5525 Handle<String> name = property->key()->AsPropertyName(); 5528 Handle<String> name = property->key()->AsPropertyName();
5526 HInstruction* store; 5529 HInstruction* store;
5527 if (map.is_null()) { 5530 if (map.is_null()) {
5528 // If we don't know the monomorphic type, do a generic store. 5531 // If we don't know the monomorphic type, do a generic store.
5529 CHECK_ALIVE(store = BuildNamedGeneric( 5532 CHECK_ALIVE(store = BuildNamedGeneric(
5530 STORE, literal, name, value)); 5533 STORE, NULL, literal, name, value));
5531 } else { 5534 } else {
5532 PropertyAccessInfo info(this, STORE, ToType(map), name); 5535 PropertyAccessInfo info(this, STORE, ToType(map), name);
5533 if (info.CanAccessMonomorphic()) { 5536 if (info.CanAccessMonomorphic()) {
5534 HValue* checked_literal = Add<HCheckMaps>(literal, map); 5537 HValue* checked_literal = Add<HCheckMaps>(literal, map);
5535 ASSERT(!info.lookup()->IsPropertyCallbacks()); 5538 ASSERT(!info.lookup()->IsPropertyCallbacks());
5536 store = BuildMonomorphicAccess( 5539 store = BuildMonomorphicAccess(
5537 &info, literal, checked_literal, value, 5540 &info, literal, checked_literal, value,
5538 BailoutId::None(), BailoutId::None()); 5541 BailoutId::None(), BailoutId::None());
5539 } else { 5542 } else {
5540 CHECK_ALIVE(store = BuildNamedGeneric( 5543 CHECK_ALIVE(store = BuildNamedGeneric(
5541 STORE, literal, name, value)); 5544 STORE, NULL, literal, name, value));
5542 } 5545 }
5543 } 5546 }
5544 AddInstruction(store); 5547 AddInstruction(store);
5545 if (store->HasObservableSideEffects()) { 5548 if (store->HasObservableSideEffects()) {
5546 Add<HSimulate>(key->id(), REMOVABLE_SIMULATE); 5549 Add<HSimulate>(key->id(), REMOVABLE_SIMULATE);
5547 } 5550 }
5548 } else { 5551 } else {
5549 CHECK_ALIVE(VisitForEffect(value)); 5552 CHECK_ALIVE(VisitForEffect(value));
5550 } 5553 }
5551 break; 5554 break;
(...skipping 584 matching lines...) Expand 10 before | Expand all | Expand 10 after
6136 if (info->IsLoad()) { 6139 if (info->IsLoad()) {
6137 return New<HConstant>(info->constant()); 6140 return New<HConstant>(info->constant());
6138 } else { 6141 } else {
6139 return New<HCheckValue>(value, Handle<JSFunction>::cast(info->constant())); 6142 return New<HCheckValue>(value, Handle<JSFunction>::cast(info->constant()));
6140 } 6143 }
6141 } 6144 }
6142 6145
6143 6146
6144 void HOptimizedGraphBuilder::HandlePolymorphicNamedFieldAccess( 6147 void HOptimizedGraphBuilder::HandlePolymorphicNamedFieldAccess(
6145 PropertyAccessType access_type, 6148 PropertyAccessType access_type,
6149 Expression* expr,
6146 BailoutId ast_id, 6150 BailoutId ast_id,
6147 BailoutId return_id, 6151 BailoutId return_id,
6148 HValue* object, 6152 HValue* object,
6149 HValue* value, 6153 HValue* value,
6150 SmallMapList* types, 6154 SmallMapList* types,
6151 Handle<String> name) { 6155 Handle<String> name) {
6152 // Something did not match; must use a polymorphic load. 6156 // Something did not match; must use a polymorphic load.
6153 int count = 0; 6157 int count = 0;
6154 HBasicBlock* join = NULL; 6158 HBasicBlock* join = NULL;
6155 HBasicBlock* number_block = NULL; 6159 HBasicBlock* number_block = NULL;
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after
6249 if (current_block() != NULL) Goto(join); 6253 if (current_block() != NULL) Goto(join);
6250 set_current_block(if_false); 6254 set_current_block(if_false);
6251 } 6255 }
6252 6256
6253 // Finish up. Unconditionally deoptimize if we've handled all the maps we 6257 // Finish up. Unconditionally deoptimize if we've handled all the maps we
6254 // know about and do not want to handle ones we've never seen. Otherwise 6258 // know about and do not want to handle ones we've never seen. Otherwise
6255 // use a generic IC. 6259 // use a generic IC.
6256 if (count == types->length() && FLAG_deoptimize_uncommon_cases) { 6260 if (count == types->length() && FLAG_deoptimize_uncommon_cases) {
6257 FinishExitWithHardDeoptimization("Uknown map in polymorphic access"); 6261 FinishExitWithHardDeoptimization("Uknown map in polymorphic access");
6258 } else { 6262 } else {
6259 HInstruction* instr = BuildNamedGeneric(access_type, object, name, value); 6263 HInstruction* instr = BuildNamedGeneric(access_type, expr, object, name,
6264 value);
6260 AddInstruction(instr); 6265 AddInstruction(instr);
6261 if (!ast_context()->IsEffect()) Push(access_type == LOAD ? instr : value); 6266 if (!ast_context()->IsEffect()) Push(access_type == LOAD ? instr : value);
6262 6267
6263 if (join != NULL) { 6268 if (join != NULL) {
6264 Goto(join); 6269 Goto(join);
6265 } else { 6270 } else {
6266 Add<HSimulate>(ast_id, REMOVABLE_SIMULATE); 6271 Add<HSimulate>(ast_id, REMOVABLE_SIMULATE);
6267 if (!ast_context()->IsEffect()) ast_context()->ReturnValue(Pop()); 6272 if (!ast_context()->IsEffect()) ast_context()->ReturnValue(Pop());
6268 return; 6273 return;
6269 } 6274 }
(...skipping 426 matching lines...) Expand 10 before | Expand all | Expand 10 after
6696 return Add<HConstant>(c_string->StringValue()->length()); 6701 return Add<HConstant>(c_string->StringValue()->length());
6697 } 6702 }
6698 } 6703 }
6699 return Add<HLoadNamedField>(string, static_cast<HValue*>(NULL), 6704 return Add<HLoadNamedField>(string, static_cast<HValue*>(NULL),
6700 HObjectAccess::ForStringLength()); 6705 HObjectAccess::ForStringLength());
6701 } 6706 }
6702 6707
6703 6708
6704 HInstruction* HOptimizedGraphBuilder::BuildNamedGeneric( 6709 HInstruction* HOptimizedGraphBuilder::BuildNamedGeneric(
6705 PropertyAccessType access_type, 6710 PropertyAccessType access_type,
6711 Expression* expr,
6706 HValue* object, 6712 HValue* object,
6707 Handle<String> name, 6713 Handle<String> name,
6708 HValue* value, 6714 HValue* value,
6709 bool is_uninitialized) { 6715 bool is_uninitialized) {
6710 if (is_uninitialized) { 6716 if (is_uninitialized) {
6711 Add<HDeoptimize>("Insufficient type feedback for generic named access", 6717 Add<HDeoptimize>("Insufficient type feedback for generic named access",
6712 Deoptimizer::SOFT); 6718 Deoptimizer::SOFT);
6713 } 6719 }
6714 if (access_type == LOAD) { 6720 if (access_type == LOAD) {
6715 return New<HLoadNamedGeneric>(object, name); 6721 HLoadNamedGeneric* result = New<HLoadNamedGeneric>(object, name);
6722 if (FLAG_vector_ics) {
6723 result->set_slot(expr->AsProperty()->PropertyFeedbackSlot());
6724 }
6725 return result;
6716 } else { 6726 } else {
6717 return New<HStoreNamedGeneric>(object, name, value, function_strict_mode()); 6727 return New<HStoreNamedGeneric>(object, name, value, function_strict_mode());
6718 } 6728 }
6719 } 6729 }
6720 6730
6721 6731
6722 6732
6723 HInstruction* HOptimizedGraphBuilder::BuildKeyedGeneric( 6733 HInstruction* HOptimizedGraphBuilder::BuildKeyedGeneric(
6724 PropertyAccessType access_type, 6734 PropertyAccessType access_type,
6735 Expression* expr,
6725 HValue* object, 6736 HValue* object,
6726 HValue* key, 6737 HValue* key,
6727 HValue* value) { 6738 HValue* value) {
6728 if (access_type == LOAD) { 6739 if (access_type == LOAD) {
6729 return New<HLoadKeyedGeneric>(object, key); 6740 HLoadKeyedGeneric* result = New<HLoadKeyedGeneric>(object, key);
6741 if (FLAG_vector_ics) {
6742 result->set_slot(expr->AsProperty()->PropertyFeedbackSlot());
6743 }
6744 return result;
6730 } else { 6745 } else {
6731 return New<HStoreKeyedGeneric>(object, key, value, function_strict_mode()); 6746 return New<HStoreKeyedGeneric>(object, key, value, function_strict_mode());
6732 } 6747 }
6733 } 6748 }
6734 6749
6735 6750
6736 LoadKeyedHoleMode HOptimizedGraphBuilder::BuildKeyedHoleMode(Handle<Map> map) { 6751 LoadKeyedHoleMode HOptimizedGraphBuilder::BuildKeyedHoleMode(Handle<Map> map) {
6737 // Loads from a "stock" fast holey double arrays can elide the hole check. 6752 // Loads from a "stock" fast holey double arrays can elide the hole check.
6738 LoadKeyedHoleMode load_mode = NEVER_RETURN_HOLE; 6753 LoadKeyedHoleMode load_mode = NEVER_RETURN_HOLE;
6739 if (*map == isolate()->get_initial_js_array_map(FAST_HOLEY_DOUBLE_ELEMENTS) && 6754 if (*map == isolate()->get_initial_js_array_map(FAST_HOLEY_DOUBLE_ELEMENTS) &&
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after
6845 HInstruction* instr = BuildUncheckedMonomorphicElementAccess( 6860 HInstruction* instr = BuildUncheckedMonomorphicElementAccess(
6846 checked_object, key, val, 6861 checked_object, key, val,
6847 most_general_consolidated_map->instance_type() == JS_ARRAY_TYPE, 6862 most_general_consolidated_map->instance_type() == JS_ARRAY_TYPE,
6848 consolidated_elements_kind, 6863 consolidated_elements_kind,
6849 LOAD, NEVER_RETURN_HOLE, STANDARD_STORE); 6864 LOAD, NEVER_RETURN_HOLE, STANDARD_STORE);
6850 return instr; 6865 return instr;
6851 } 6866 }
6852 6867
6853 6868
6854 HValue* HOptimizedGraphBuilder::HandlePolymorphicElementAccess( 6869 HValue* HOptimizedGraphBuilder::HandlePolymorphicElementAccess(
6870 Expression* expr,
6855 HValue* object, 6871 HValue* object,
6856 HValue* key, 6872 HValue* key,
6857 HValue* val, 6873 HValue* val,
6858 SmallMapList* maps, 6874 SmallMapList* maps,
6859 PropertyAccessType access_type, 6875 PropertyAccessType access_type,
6860 KeyedAccessStoreMode store_mode, 6876 KeyedAccessStoreMode store_mode,
6861 bool* has_side_effects) { 6877 bool* has_side_effects) {
6862 *has_side_effects = false; 6878 *has_side_effects = false;
6863 BuildCheckHeapObject(object); 6879 BuildCheckHeapObject(object);
6864 6880
(...skipping 11 matching lines...) Expand all
6876 // Collect possible transition targets. 6892 // Collect possible transition targets.
6877 MapHandleList possible_transitioned_maps(maps->length()); 6893 MapHandleList possible_transitioned_maps(maps->length());
6878 for (int i = 0; i < maps->length(); ++i) { 6894 for (int i = 0; i < maps->length(); ++i) {
6879 Handle<Map> map = maps->at(i); 6895 Handle<Map> map = maps->at(i);
6880 ElementsKind elements_kind = map->elements_kind(); 6896 ElementsKind elements_kind = map->elements_kind();
6881 if (IsFastElementsKind(elements_kind) && 6897 if (IsFastElementsKind(elements_kind) &&
6882 elements_kind != GetInitialFastElementsKind()) { 6898 elements_kind != GetInitialFastElementsKind()) {
6883 possible_transitioned_maps.Add(map); 6899 possible_transitioned_maps.Add(map);
6884 } 6900 }
6885 if (elements_kind == SLOPPY_ARGUMENTS_ELEMENTS) { 6901 if (elements_kind == SLOPPY_ARGUMENTS_ELEMENTS) {
6886 HInstruction* result = BuildKeyedGeneric(access_type, object, key, val); 6902 HInstruction* result = BuildKeyedGeneric(access_type, expr, object, key,
6903 val);
6887 *has_side_effects = result->HasObservableSideEffects(); 6904 *has_side_effects = result->HasObservableSideEffects();
6888 return AddInstruction(result); 6905 return AddInstruction(result);
6889 } 6906 }
6890 } 6907 }
6891 // Get transition target for each map (NULL == no transition). 6908 // Get transition target for each map (NULL == no transition).
6892 for (int i = 0; i < maps->length(); ++i) { 6909 for (int i = 0; i < maps->length(); ++i) {
6893 Handle<Map> map = maps->at(i); 6910 Handle<Map> map = maps->at(i);
6894 Handle<Map> transitioned_map = 6911 Handle<Map> transitioned_map =
6895 map->FindTransitionedMap(&possible_transitioned_maps); 6912 map->FindTransitionedMap(&possible_transitioned_maps);
6896 transition_target.Add(transitioned_map); 6913 transition_target.Add(transitioned_map);
(...skipping 16 matching lines...) Expand all
6913 } 6930 }
6914 6931
6915 // If only one map is left after transitioning, handle this case 6932 // If only one map is left after transitioning, handle this case
6916 // monomorphically. 6933 // monomorphically.
6917 ASSERT(untransitionable_maps.length() >= 1); 6934 ASSERT(untransitionable_maps.length() >= 1);
6918 if (untransitionable_maps.length() == 1) { 6935 if (untransitionable_maps.length() == 1) {
6919 Handle<Map> untransitionable_map = untransitionable_maps[0]; 6936 Handle<Map> untransitionable_map = untransitionable_maps[0];
6920 HInstruction* instr = NULL; 6937 HInstruction* instr = NULL;
6921 if (untransitionable_map->has_slow_elements_kind() || 6938 if (untransitionable_map->has_slow_elements_kind() ||
6922 !untransitionable_map->IsJSObjectMap()) { 6939 !untransitionable_map->IsJSObjectMap()) {
6923 instr = AddInstruction(BuildKeyedGeneric(access_type, object, key, val)); 6940 instr = AddInstruction(BuildKeyedGeneric(access_type, expr, object, key,
6941 val));
6924 } else { 6942 } else {
6925 instr = BuildMonomorphicElementAccess( 6943 instr = BuildMonomorphicElementAccess(
6926 object, key, val, transition, untransitionable_map, access_type, 6944 object, key, val, transition, untransitionable_map, access_type,
6927 store_mode); 6945 store_mode);
6928 } 6946 }
6929 *has_side_effects |= instr->HasObservableSideEffects(); 6947 *has_side_effects |= instr->HasObservableSideEffects();
6930 return access_type == STORE ? NULL : instr; 6948 return access_type == STORE ? NULL : instr;
6931 } 6949 }
6932 6950
6933 HBasicBlock* join = graph()->CreateBasicBlock(); 6951 HBasicBlock* join = graph()->CreateBasicBlock();
6934 6952
6935 for (int i = 0; i < untransitionable_maps.length(); ++i) { 6953 for (int i = 0; i < untransitionable_maps.length(); ++i) {
6936 Handle<Map> map = untransitionable_maps[i]; 6954 Handle<Map> map = untransitionable_maps[i];
6937 if (!map->IsJSObjectMap()) continue; 6955 if (!map->IsJSObjectMap()) continue;
6938 ElementsKind elements_kind = map->elements_kind(); 6956 ElementsKind elements_kind = map->elements_kind();
6939 HBasicBlock* this_map = graph()->CreateBasicBlock(); 6957 HBasicBlock* this_map = graph()->CreateBasicBlock();
6940 HBasicBlock* other_map = graph()->CreateBasicBlock(); 6958 HBasicBlock* other_map = graph()->CreateBasicBlock();
6941 HCompareMap* mapcompare = 6959 HCompareMap* mapcompare =
6942 New<HCompareMap>(object, map, this_map, other_map); 6960 New<HCompareMap>(object, map, this_map, other_map);
6943 FinishCurrentBlock(mapcompare); 6961 FinishCurrentBlock(mapcompare);
6944 6962
6945 set_current_block(this_map); 6963 set_current_block(this_map);
6946 HInstruction* access = NULL; 6964 HInstruction* access = NULL;
6947 if (IsDictionaryElementsKind(elements_kind)) { 6965 if (IsDictionaryElementsKind(elements_kind)) {
6948 access = AddInstruction(BuildKeyedGeneric(access_type, object, key, val)); 6966 access = AddInstruction(BuildKeyedGeneric(access_type, expr, object, key,
6967 val));
6949 } else { 6968 } else {
6950 ASSERT(IsFastElementsKind(elements_kind) || 6969 ASSERT(IsFastElementsKind(elements_kind) ||
6951 IsExternalArrayElementsKind(elements_kind) || 6970 IsExternalArrayElementsKind(elements_kind) ||
6952 IsFixedTypedArrayElementsKind(elements_kind)); 6971 IsFixedTypedArrayElementsKind(elements_kind));
6953 LoadKeyedHoleMode load_mode = BuildKeyedHoleMode(map); 6972 LoadKeyedHoleMode load_mode = BuildKeyedHoleMode(map);
6954 // Happily, mapcompare is a checked object. 6973 // Happily, mapcompare is a checked object.
6955 access = BuildUncheckedMonomorphicElementAccess( 6974 access = BuildUncheckedMonomorphicElementAccess(
6956 mapcompare, key, val, 6975 mapcompare, key, val,
6957 map->instance_type() == JS_ARRAY_TYPE, 6976 map->instance_type() == JS_ARRAY_TYPE,
6958 elements_kind, access_type, 6977 elements_kind, access_type,
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
7009 force_generic = true; 7028 force_generic = true;
7010 monomorphic = false; 7029 monomorphic = false;
7011 break; 7030 break;
7012 } 7031 }
7013 } 7032 }
7014 } 7033 }
7015 7034
7016 if (monomorphic) { 7035 if (monomorphic) {
7017 Handle<Map> map = types->first(); 7036 Handle<Map> map = types->first();
7018 if (map->has_slow_elements_kind() || !map->IsJSObjectMap()) { 7037 if (map->has_slow_elements_kind() || !map->IsJSObjectMap()) {
7019 instr = AddInstruction(BuildKeyedGeneric(access_type, obj, key, val)); 7038 instr = AddInstruction(BuildKeyedGeneric(access_type, expr, obj, key,
7039 val));
7020 } else { 7040 } else {
7021 BuildCheckHeapObject(obj); 7041 BuildCheckHeapObject(obj);
7022 instr = BuildMonomorphicElementAccess( 7042 instr = BuildMonomorphicElementAccess(
7023 obj, key, val, NULL, map, access_type, expr->GetStoreMode()); 7043 obj, key, val, NULL, map, access_type, expr->GetStoreMode());
7024 } 7044 }
7025 } else if (!force_generic && (types != NULL && !types->is_empty())) { 7045 } else if (!force_generic && (types != NULL && !types->is_empty())) {
7026 return HandlePolymorphicElementAccess( 7046 return HandlePolymorphicElementAccess(
7027 obj, key, val, types, access_type, 7047 expr, obj, key, val, types, access_type,
7028 expr->GetStoreMode(), has_side_effects); 7048 expr->GetStoreMode(), has_side_effects);
7029 } else { 7049 } else {
7030 if (access_type == STORE) { 7050 if (access_type == STORE) {
7031 if (expr->IsAssignment() && 7051 if (expr->IsAssignment() &&
7032 expr->AsAssignment()->HasNoTypeInformation()) { 7052 expr->AsAssignment()->HasNoTypeInformation()) {
7033 Add<HDeoptimize>("Insufficient type feedback for keyed store", 7053 Add<HDeoptimize>("Insufficient type feedback for keyed store",
7034 Deoptimizer::SOFT); 7054 Deoptimizer::SOFT);
7035 } 7055 }
7036 } else { 7056 } else {
7037 if (expr->AsProperty()->HasNoTypeInformation()) { 7057 if (expr->AsProperty()->HasNoTypeInformation()) {
7038 Add<HDeoptimize>("Insufficient type feedback for keyed load", 7058 Add<HDeoptimize>("Insufficient type feedback for keyed load",
7039 Deoptimizer::SOFT); 7059 Deoptimizer::SOFT);
7040 } 7060 }
7041 } 7061 }
7042 instr = AddInstruction(BuildKeyedGeneric(access_type, obj, key, val)); 7062 instr = AddInstruction(BuildKeyedGeneric(access_type, expr, obj, key, val));
7043 } 7063 }
7044 *has_side_effects = instr->HasObservableSideEffects(); 7064 *has_side_effects = instr->HasObservableSideEffects();
7045 return instr; 7065 return instr;
7046 } 7066 }
7047 7067
7048 7068
7049 void HOptimizedGraphBuilder::EnsureArgumentsArePushedForAccess() { 7069 void HOptimizedGraphBuilder::EnsureArgumentsArePushedForAccess() {
7050 // Outermost function already has arguments on the stack. 7070 // Outermost function already has arguments on the stack.
7051 if (function_state()->outer() == NULL) return; 7071 if (function_state()->outer() == NULL) return;
7052 7072
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
7133 HValue* value, 7153 HValue* value,
7134 bool is_uninitialized) { 7154 bool is_uninitialized) {
7135 SmallMapList* types; 7155 SmallMapList* types;
7136 ComputeReceiverTypes(expr, object, &types, zone()); 7156 ComputeReceiverTypes(expr, object, &types, zone());
7137 ASSERT(types != NULL); 7157 ASSERT(types != NULL);
7138 7158
7139 if (types->length() > 0) { 7159 if (types->length() > 0) {
7140 PropertyAccessInfo info(this, access, ToType(types->first()), name); 7160 PropertyAccessInfo info(this, access, ToType(types->first()), name);
7141 if (!info.CanAccessAsMonomorphic(types)) { 7161 if (!info.CanAccessAsMonomorphic(types)) {
7142 HandlePolymorphicNamedFieldAccess( 7162 HandlePolymorphicNamedFieldAccess(
7143 access, ast_id, return_id, object, value, types, name); 7163 access, expr, ast_id, return_id, object, value, types, name);
7144 return NULL; 7164 return NULL;
7145 } 7165 }
7146 7166
7147 HValue* checked_object; 7167 HValue* checked_object;
7148 // Type::Number() is only supported by polymorphic load/call handling. 7168 // Type::Number() is only supported by polymorphic load/call handling.
7149 ASSERT(!info.type()->Is(Type::Number())); 7169 ASSERT(!info.type()->Is(Type::Number()));
7150 BuildCheckHeapObject(object); 7170 BuildCheckHeapObject(object);
7151 if (AreStringTypes(types)) { 7171 if (AreStringTypes(types)) {
7152 checked_object = 7172 checked_object =
7153 Add<HCheckInstanceType>(object, HCheckInstanceType::IS_STRING); 7173 Add<HCheckInstanceType>(object, HCheckInstanceType::IS_STRING);
7154 } else { 7174 } else {
7155 checked_object = Add<HCheckMaps>(object, types); 7175 checked_object = Add<HCheckMaps>(object, types);
7156 } 7176 }
7157 return BuildMonomorphicAccess( 7177 return BuildMonomorphicAccess(
7158 &info, object, checked_object, value, ast_id, return_id); 7178 &info, object, checked_object, value, ast_id, return_id);
7159 } 7179 }
7160 7180
7161 return BuildNamedGeneric(access, object, name, value, is_uninitialized); 7181 return BuildNamedGeneric(access, expr, object, name, value, is_uninitialized);
7162 } 7182 }
7163 7183
7164 7184
7165 void HOptimizedGraphBuilder::PushLoad(Property* expr, 7185 void HOptimizedGraphBuilder::PushLoad(Property* expr,
7166 HValue* object, 7186 HValue* object,
7167 HValue* key) { 7187 HValue* key) {
7168 ValueContext for_value(this, ARGUMENTS_NOT_ALLOWED); 7188 ValueContext for_value(this, ARGUMENTS_NOT_ALLOWED);
7169 Push(object); 7189 Push(object);
7170 if (key != NULL) Push(key); 7190 if (key != NULL) Push(key);
7171 BuildLoad(expr, expr->LoadId()); 7191 BuildLoad(expr, expr->LoadId());
(...skipping 303 matching lines...) Expand 10 before | Expand all | Expand 10 after
7475 } 7495 }
7476 7496
7477 // Finish up. Unconditionally deoptimize if we've handled all the maps we 7497 // Finish up. Unconditionally deoptimize if we've handled all the maps we
7478 // know about and do not want to handle ones we've never seen. Otherwise 7498 // know about and do not want to handle ones we've never seen. Otherwise
7479 // use a generic IC. 7499 // use a generic IC.
7480 if (ordered_functions == types->length() && FLAG_deoptimize_uncommon_cases) { 7500 if (ordered_functions == types->length() && FLAG_deoptimize_uncommon_cases) {
7481 FinishExitWithHardDeoptimization("Unknown map in polymorphic call"); 7501 FinishExitWithHardDeoptimization("Unknown map in polymorphic call");
7482 } else { 7502 } else {
7483 Property* prop = expr->expression()->AsProperty(); 7503 Property* prop = expr->expression()->AsProperty();
7484 HInstruction* function = BuildNamedGeneric( 7504 HInstruction* function = BuildNamedGeneric(
7485 LOAD, receiver, name, NULL, prop->IsUninitialized()); 7505 LOAD, prop, receiver, name, NULL, prop->IsUninitialized());
7486 AddInstruction(function); 7506 AddInstruction(function);
7487 Push(function); 7507 Push(function);
7488 AddSimulate(prop->LoadId(), REMOVABLE_SIMULATE); 7508 AddSimulate(prop->LoadId(), REMOVABLE_SIMULATE);
7489 7509
7490 environment()->SetExpressionStackAt(1, function); 7510 environment()->SetExpressionStackAt(1, function);
7491 environment()->SetExpressionStackAt(0, receiver); 7511 environment()->SetExpressionStackAt(0, receiver);
7492 CHECK_ALIVE(VisitExpressions(expr->arguments())); 7512 CHECK_ALIVE(VisitExpressions(expr->arguments()));
7493 7513
7494 CallFunctionFlags flags = receiver->type().IsJSObject() 7514 CallFunctionFlags flags = receiver->type().IsJSObject()
7495 ? NO_CALL_FUNCTION_FLAGS : CALL_AS_METHOD; 7515 ? NO_CALL_FUNCTION_FLAGS : CALL_AS_METHOD;
(...skipping 4879 matching lines...) Expand 10 before | Expand all | Expand 10 after
12375 if (ShouldProduceTraceOutput()) { 12395 if (ShouldProduceTraceOutput()) {
12376 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); 12396 isolate()->GetHTracer()->TraceHydrogen(name(), graph_);
12377 } 12397 }
12378 12398
12379 #ifdef DEBUG 12399 #ifdef DEBUG
12380 graph_->Verify(false); // No full verify. 12400 graph_->Verify(false); // No full verify.
12381 #endif 12401 #endif
12382 } 12402 }
12383 12403
12384 } } // namespace v8::internal 12404 } } // namespace v8::internal
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698