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

Side by Side Diff: src/hydrogen.cc

Issue 697643002: Ensure we don't try to inline raw access to indexed interceptor receivers. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 6 years, 1 month 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 | « no previous file | 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 // 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 <sstream> 7 #include <sstream>
8 8
9 #include "src/v8.h" 9 #include "src/v8.h"
10 10
(...skipping 6923 matching lines...) Expand 10 before | Expand all | Expand 10 after
6934 6934
6935 LoadKeyedHoleMode load_mode = BuildKeyedHoleMode(map); 6935 LoadKeyedHoleMode load_mode = BuildKeyedHoleMode(map);
6936 return BuildUncheckedMonomorphicElementAccess( 6936 return BuildUncheckedMonomorphicElementAccess(
6937 checked_object, key, val, 6937 checked_object, key, val,
6938 map->instance_type() == JS_ARRAY_TYPE, 6938 map->instance_type() == JS_ARRAY_TYPE,
6939 map->elements_kind(), access_type, 6939 map->elements_kind(), access_type,
6940 load_mode, store_mode); 6940 load_mode, store_mode);
6941 } 6941 }
6942 6942
6943 6943
6944 static bool CanInlineElementAccess(Handle<Map> map) {
6945 return map->IsJSObjectMap() && !map->has_slow_elements_kind() &&
6946 !map->has_indexed_interceptor();
6947 }
6948
6949
6944 HInstruction* HOptimizedGraphBuilder::TryBuildConsolidatedElementLoad( 6950 HInstruction* HOptimizedGraphBuilder::TryBuildConsolidatedElementLoad(
6945 HValue* object, 6951 HValue* object,
6946 HValue* key, 6952 HValue* key,
6947 HValue* val, 6953 HValue* val,
6948 SmallMapList* maps) { 6954 SmallMapList* maps) {
6949 // For polymorphic loads of similar elements kinds (i.e. all tagged or all 6955 // For polymorphic loads of similar elements kinds (i.e. all tagged or all
6950 // double), always use the "worst case" code without a transition. This is 6956 // double), always use the "worst case" code without a transition. This is
6951 // much faster than transitioning the elements to the worst case, trading a 6957 // much faster than transitioning the elements to the worst case, trading a
6952 // HTransitionElements for a HCheckMaps, and avoiding mutation of the array. 6958 // HTransitionElements for a HCheckMaps, and avoiding mutation of the array.
6953 bool has_double_maps = false; 6959 bool has_double_maps = false;
6954 bool has_smi_or_object_maps = false; 6960 bool has_smi_or_object_maps = false;
6955 bool has_js_array_access = false; 6961 bool has_js_array_access = false;
6956 bool has_non_js_array_access = false; 6962 bool has_non_js_array_access = false;
6957 bool has_seen_holey_elements = false; 6963 bool has_seen_holey_elements = false;
6958 Handle<Map> most_general_consolidated_map; 6964 Handle<Map> most_general_consolidated_map;
6959 for (int i = 0; i < maps->length(); ++i) { 6965 for (int i = 0; i < maps->length(); ++i) {
6960 Handle<Map> map = maps->at(i); 6966 Handle<Map> map = maps->at(i);
6961 if (!map->IsJSObjectMap()) return NULL; 6967 if (!CanInlineElementAccess(map)) return NULL;
6962 // Don't allow mixing of JSArrays with JSObjects. 6968 // Don't allow mixing of JSArrays with JSObjects.
6963 if (map->instance_type() == JS_ARRAY_TYPE) { 6969 if (map->instance_type() == JS_ARRAY_TYPE) {
6964 if (has_non_js_array_access) return NULL; 6970 if (has_non_js_array_access) return NULL;
6965 has_js_array_access = true; 6971 has_js_array_access = true;
6966 } else if (has_js_array_access) { 6972 } else if (has_js_array_access) {
6967 return NULL; 6973 return NULL;
6968 } else { 6974 } else {
6969 has_non_js_array_access = true; 6975 has_non_js_array_access = true;
6970 } 6976 }
6971 // Don't allow mixed, incompatible elements kinds. 6977 // Don't allow mixed, incompatible elements kinds.
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
7029 } 7035 }
7030 7036
7031 // Elements_kind transition support. 7037 // Elements_kind transition support.
7032 MapHandleList transition_target(maps->length()); 7038 MapHandleList transition_target(maps->length());
7033 // Collect possible transition targets. 7039 // Collect possible transition targets.
7034 MapHandleList possible_transitioned_maps(maps->length()); 7040 MapHandleList possible_transitioned_maps(maps->length());
7035 for (int i = 0; i < maps->length(); ++i) { 7041 for (int i = 0; i < maps->length(); ++i) {
7036 Handle<Map> map = maps->at(i); 7042 Handle<Map> map = maps->at(i);
7037 DCHECK(!map->IsStringMap()); 7043 DCHECK(!map->IsStringMap());
7038 ElementsKind elements_kind = map->elements_kind(); 7044 ElementsKind elements_kind = map->elements_kind();
7039 if (IsFastElementsKind(elements_kind) && 7045 if (CanInlineElementAccess(map) && IsFastElementsKind(elements_kind) &&
7040 elements_kind != GetInitialFastElementsKind()) { 7046 elements_kind != GetInitialFastElementsKind()) {
7041 possible_transitioned_maps.Add(map); 7047 possible_transitioned_maps.Add(map);
7042 } 7048 }
7043 if (elements_kind == SLOPPY_ARGUMENTS_ELEMENTS) { 7049 if (elements_kind == SLOPPY_ARGUMENTS_ELEMENTS) {
7044 HInstruction* result = BuildKeyedGeneric(access_type, expr, object, key, 7050 HInstruction* result = BuildKeyedGeneric(access_type, expr, object, key,
7045 val); 7051 val);
7046 *has_side_effects = result->HasObservableSideEffects(); 7052 *has_side_effects = result->HasObservableSideEffects();
7047 return AddInstruction(result); 7053 return AddInstruction(result);
7048 } 7054 }
7049 } 7055 }
(...skipping 20 matching lines...) Expand all
7070 untransitionable_maps.Add(map); 7076 untransitionable_maps.Add(map);
7071 } 7077 }
7072 } 7078 }
7073 7079
7074 // If only one map is left after transitioning, handle this case 7080 // If only one map is left after transitioning, handle this case
7075 // monomorphically. 7081 // monomorphically.
7076 DCHECK(untransitionable_maps.length() >= 1); 7082 DCHECK(untransitionable_maps.length() >= 1);
7077 if (untransitionable_maps.length() == 1) { 7083 if (untransitionable_maps.length() == 1) {
7078 Handle<Map> untransitionable_map = untransitionable_maps[0]; 7084 Handle<Map> untransitionable_map = untransitionable_maps[0];
7079 HInstruction* instr = NULL; 7085 HInstruction* instr = NULL;
7080 if (untransitionable_map->has_slow_elements_kind() || 7086 if (!CanInlineElementAccess(untransitionable_map)) {
7081 !untransitionable_map->IsJSObjectMap()) {
7082 instr = AddInstruction(BuildKeyedGeneric(access_type, expr, object, key, 7087 instr = AddInstruction(BuildKeyedGeneric(access_type, expr, object, key,
7083 val)); 7088 val));
7084 } else { 7089 } else {
7085 instr = BuildMonomorphicElementAccess( 7090 instr = BuildMonomorphicElementAccess(
7086 object, key, val, transition, untransitionable_map, access_type, 7091 object, key, val, transition, untransitionable_map, access_type,
7087 store_mode); 7092 store_mode);
7088 } 7093 }
7089 *has_side_effects |= instr->HasObservableSideEffects(); 7094 *has_side_effects |= instr->HasObservableSideEffects();
7090 return access_type == STORE ? val : instr; 7095 return access_type == STORE ? val : instr;
7091 } 7096 }
7092 7097
7093 HBasicBlock* join = graph()->CreateBasicBlock(); 7098 HBasicBlock* join = graph()->CreateBasicBlock();
7094 7099
7095 for (int i = 0; i < untransitionable_maps.length(); ++i) { 7100 for (int i = 0; i < untransitionable_maps.length(); ++i) {
7096 Handle<Map> map = untransitionable_maps[i]; 7101 Handle<Map> map = untransitionable_maps[i];
7097 if (!map->IsJSObjectMap()) continue;
7098 ElementsKind elements_kind = map->elements_kind(); 7102 ElementsKind elements_kind = map->elements_kind();
7099 HBasicBlock* this_map = graph()->CreateBasicBlock(); 7103 HBasicBlock* this_map = graph()->CreateBasicBlock();
7100 HBasicBlock* other_map = graph()->CreateBasicBlock(); 7104 HBasicBlock* other_map = graph()->CreateBasicBlock();
7101 HCompareMap* mapcompare = 7105 HCompareMap* mapcompare =
7102 New<HCompareMap>(object, map, this_map, other_map); 7106 New<HCompareMap>(object, map, this_map, other_map);
7103 FinishCurrentBlock(mapcompare); 7107 FinishCurrentBlock(mapcompare);
7104 7108
7105 set_current_block(this_map); 7109 set_current_block(this_map);
7106 HInstruction* access = NULL; 7110 HInstruction* access = NULL;
7107 if (IsDictionaryElementsKind(elements_kind)) { 7111 if (!CanInlineElementAccess(map)) {
7108 access = AddInstruction(BuildKeyedGeneric(access_type, expr, object, key, 7112 access = AddInstruction(BuildKeyedGeneric(access_type, expr, object, key,
7109 val)); 7113 val));
7110 } else { 7114 } else {
7111 DCHECK(IsFastElementsKind(elements_kind) || 7115 DCHECK(IsFastElementsKind(elements_kind) ||
7112 IsExternalArrayElementsKind(elements_kind) || 7116 IsExternalArrayElementsKind(elements_kind) ||
7113 IsFixedTypedArrayElementsKind(elements_kind)); 7117 IsFixedTypedArrayElementsKind(elements_kind));
7114 LoadKeyedHoleMode load_mode = BuildKeyedHoleMode(map); 7118 LoadKeyedHoleMode load_mode = BuildKeyedHoleMode(map);
7115 // Happily, mapcompare is a checked object. 7119 // Happily, mapcompare is a checked object.
7116 access = BuildUncheckedMonomorphicElementAccess( 7120 access = BuildUncheckedMonomorphicElementAccess(
7117 mapcompare, key, val, 7121 mapcompare, key, val,
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
7208 Handle<Map> current_map = types->at(i); 7212 Handle<Map> current_map = types->at(i);
7209 if (current_map->IsStringMap()) { 7213 if (current_map->IsStringMap()) {
7210 force_generic = true; 7214 force_generic = true;
7211 break; 7215 break;
7212 } 7216 }
7213 } 7217 }
7214 } 7218 }
7215 7219
7216 if (monomorphic) { 7220 if (monomorphic) {
7217 Handle<Map> map = types->first(); 7221 Handle<Map> map = types->first();
7218 if (map->has_slow_elements_kind() || !map->IsJSObjectMap()) { 7222 if (!CanInlineElementAccess(map)) {
7219 instr = AddInstruction(BuildKeyedGeneric(access_type, expr, obj, key, 7223 instr = AddInstruction(BuildKeyedGeneric(access_type, expr, obj, key,
7220 val)); 7224 val));
7221 } else { 7225 } else {
7222 BuildCheckHeapObject(obj); 7226 BuildCheckHeapObject(obj);
7223 instr = BuildMonomorphicElementAccess( 7227 instr = BuildMonomorphicElementAccess(
7224 obj, key, val, NULL, map, access_type, expr->GetStoreMode()); 7228 obj, key, val, NULL, map, access_type, expr->GetStoreMode());
7225 } 7229 }
7226 } else if (!force_generic && (types != NULL && !types->is_empty())) { 7230 } else if (!force_generic && (types != NULL && !types->is_empty())) {
7227 return HandlePolymorphicElementAccess( 7231 return HandlePolymorphicElementAccess(
7228 expr, obj, key, val, types, access_type, 7232 expr, obj, key, val, types, access_type,
(...skipping 5438 matching lines...) Expand 10 before | Expand all | Expand 10 after
12667 if (ShouldProduceTraceOutput()) { 12671 if (ShouldProduceTraceOutput()) {
12668 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); 12672 isolate()->GetHTracer()->TraceHydrogen(name(), graph_);
12669 } 12673 }
12670 12674
12671 #ifdef DEBUG 12675 #ifdef DEBUG
12672 graph_->Verify(false); // No full verify. 12676 graph_->Verify(false); // No full verify.
12673 #endif 12677 #endif
12674 } 12678 }
12675 12679
12676 } } // namespace v8::internal 12680 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698