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

Side by Side Diff: src/hydrogen.cc

Issue 137883008: Use PropertyAccessType for keyed accesses rather than "bool is_store" (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') | 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 // 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 1286 matching lines...) Expand 10 before | Expand all | Expand 10 after
1297 HConstant::cast(function)->handle(isolate())->IsJSFunction()) { 1297 HConstant::cast(function)->handle(isolate())->IsJSFunction()) {
1298 Handle<JSFunction> f = Handle<JSFunction>::cast( 1298 Handle<JSFunction> f = Handle<JSFunction>::cast(
1299 HConstant::cast(function)->handle(isolate())); 1299 HConstant::cast(function)->handle(isolate()));
1300 SharedFunctionInfo* shared = f->shared(); 1300 SharedFunctionInfo* shared = f->shared();
1301 if (!shared->is_classic_mode() || shared->native()) return object; 1301 if (!shared->is_classic_mode() || shared->native()) return object;
1302 } 1302 }
1303 return Add<HWrapReceiver>(object, function); 1303 return Add<HWrapReceiver>(object, function);
1304 } 1304 }
1305 1305
1306 1306
1307 HValue* HGraphBuilder::BuildCheckForCapacityGrow(HValue* object, 1307 HValue* HGraphBuilder::BuildCheckForCapacityGrow(
1308 HValue* elements, 1308 HValue* object,
1309 ElementsKind kind, 1309 HValue* elements,
1310 HValue* length, 1310 ElementsKind kind,
1311 HValue* key, 1311 HValue* length,
1312 bool is_js_array, 1312 HValue* key,
1313 bool is_store) { 1313 bool is_js_array,
1314 PropertyAccessType access_type) {
1314 IfBuilder length_checker(this); 1315 IfBuilder length_checker(this);
1315 1316
1316 Token::Value token = IsHoleyElementsKind(kind) ? Token::GTE : Token::EQ; 1317 Token::Value token = IsHoleyElementsKind(kind) ? Token::GTE : Token::EQ;
1317 length_checker.If<HCompareNumericAndBranch>(key, length, token); 1318 length_checker.If<HCompareNumericAndBranch>(key, length, token);
1318 1319
1319 length_checker.Then(); 1320 length_checker.Then();
1320 1321
1321 HValue* current_capacity = AddLoadFixedArrayLength(elements); 1322 HValue* current_capacity = AddLoadFixedArrayLength(elements);
1322 1323
1323 IfBuilder capacity_checker(this); 1324 IfBuilder capacity_checker(this);
(...skipping 22 matching lines...) Expand all
1346 capacity_checker.End(); 1347 capacity_checker.End();
1347 1348
1348 if (is_js_array) { 1349 if (is_js_array) {
1349 HValue* new_length = AddUncasted<HAdd>(key, graph_->GetConstant1()); 1350 HValue* new_length = AddUncasted<HAdd>(key, graph_->GetConstant1());
1350 new_length->ClearFlag(HValue::kCanOverflow); 1351 new_length->ClearFlag(HValue::kCanOverflow);
1351 1352
1352 Add<HStoreNamedField>(object, HObjectAccess::ForArrayLength(kind), 1353 Add<HStoreNamedField>(object, HObjectAccess::ForArrayLength(kind),
1353 new_length); 1354 new_length);
1354 } 1355 }
1355 1356
1356 if (is_store && kind == FAST_SMI_ELEMENTS) { 1357 if (access_type == STORE && kind == FAST_SMI_ELEMENTS) {
1357 HValue* checked_elements = environment()->Top(); 1358 HValue* checked_elements = environment()->Top();
1358 1359
1359 // Write zero to ensure that the new element is initialized with some smi. 1360 // Write zero to ensure that the new element is initialized with some smi.
1360 Add<HStoreKeyed>(checked_elements, key, graph()->GetConstant0(), kind); 1361 Add<HStoreKeyed>(checked_elements, key, graph()->GetConstant0(), kind);
1361 } 1362 }
1362 1363
1363 length_checker.Else(); 1364 length_checker.Else();
1364 Add<HBoundsCheck>(key, length); 1365 Add<HBoundsCheck>(key, length);
1365 1366
1366 environment()->Push(elements); 1367 environment()->Push(elements);
(...skipping 785 matching lines...) Expand 10 before | Expand all | Expand 10 after
2152 return Pop(); 2153 return Pop();
2153 } 2154 }
2154 2155
2155 2156
2156 HInstruction* HGraphBuilder::BuildUncheckedMonomorphicElementAccess( 2157 HInstruction* HGraphBuilder::BuildUncheckedMonomorphicElementAccess(
2157 HValue* checked_object, 2158 HValue* checked_object,
2158 HValue* key, 2159 HValue* key,
2159 HValue* val, 2160 HValue* val,
2160 bool is_js_array, 2161 bool is_js_array,
2161 ElementsKind elements_kind, 2162 ElementsKind elements_kind,
2162 bool is_store, 2163 PropertyAccessType access_type,
2163 LoadKeyedHoleMode load_mode, 2164 LoadKeyedHoleMode load_mode,
2164 KeyedAccessStoreMode store_mode) { 2165 KeyedAccessStoreMode store_mode) {
2165 ASSERT((!IsExternalArrayElementsKind(elements_kind) && 2166 ASSERT((!IsExternalArrayElementsKind(elements_kind) &&
2166 !IsFixedTypedArrayElementsKind(elements_kind)) || 2167 !IsFixedTypedArrayElementsKind(elements_kind)) ||
2167 !is_js_array); 2168 !is_js_array);
2168 // No GVNFlag is necessary for ElementsKind if there is an explicit dependency 2169 // No GVNFlag is necessary for ElementsKind if there is an explicit dependency
2169 // on a HElementsTransition instruction. The flag can also be removed if the 2170 // on a HElementsTransition instruction. The flag can also be removed if the
2170 // map to check has FAST_HOLEY_ELEMENTS, since there can be no further 2171 // map to check has FAST_HOLEY_ELEMENTS, since there can be no further
2171 // ElementsKind transitions. Finally, the dependency can be removed for stores 2172 // ElementsKind transitions. Finally, the dependency can be removed for stores
2172 // for FAST_ELEMENTS, since a transition to HOLEY elements won't change the 2173 // for FAST_ELEMENTS, since a transition to HOLEY elements won't change the
2173 // generated store code. 2174 // generated store code.
2174 if ((elements_kind == FAST_HOLEY_ELEMENTS) || 2175 if ((elements_kind == FAST_HOLEY_ELEMENTS) ||
2175 (elements_kind == FAST_ELEMENTS && is_store)) { 2176 (elements_kind == FAST_ELEMENTS && access_type == STORE)) {
2176 checked_object->ClearGVNFlag(kDependsOnElementsKind); 2177 checked_object->ClearGVNFlag(kDependsOnElementsKind);
2177 } 2178 }
2178 2179
2179 bool fast_smi_only_elements = IsFastSmiElementsKind(elements_kind); 2180 bool fast_smi_only_elements = IsFastSmiElementsKind(elements_kind);
2180 bool fast_elements = IsFastObjectElementsKind(elements_kind); 2181 bool fast_elements = IsFastObjectElementsKind(elements_kind);
2181 HValue* elements = AddLoadElements(checked_object); 2182 HValue* elements = AddLoadElements(checked_object);
2182 if (is_store && (fast_elements || fast_smi_only_elements) && 2183 if (access_type == STORE && (fast_elements || fast_smi_only_elements) &&
2183 store_mode != STORE_NO_TRANSITION_HANDLE_COW) { 2184 store_mode != STORE_NO_TRANSITION_HANDLE_COW) {
2184 HCheckMaps* check_cow_map = Add<HCheckMaps>( 2185 HCheckMaps* check_cow_map = Add<HCheckMaps>(
2185 elements, isolate()->factory()->fixed_array_map(), top_info()); 2186 elements, isolate()->factory()->fixed_array_map(), top_info());
2186 check_cow_map->ClearGVNFlag(kDependsOnElementsKind); 2187 check_cow_map->ClearGVNFlag(kDependsOnElementsKind);
2187 } 2188 }
2188 HInstruction* length = NULL; 2189 HInstruction* length = NULL;
2189 if (is_js_array) { 2190 if (is_js_array) {
2190 length = Add<HLoadNamedField>( 2191 length = Add<HLoadNamedField>(
2191 checked_object, static_cast<HValue*>(NULL), 2192 checked_object, static_cast<HValue*>(NULL),
2192 HObjectAccess::ForArrayLength(elements_kind)); 2193 HObjectAccess::ForArrayLength(elements_kind));
(...skipping 15 matching lines...) Expand all
2208 if (store_mode == STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS) { 2209 if (store_mode == STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS) {
2209 NoObservableSideEffectsScope no_effects(this); 2210 NoObservableSideEffectsScope no_effects(this);
2210 IfBuilder length_checker(this); 2211 IfBuilder length_checker(this);
2211 length_checker.If<HCompareNumericAndBranch>(key, length, Token::LT); 2212 length_checker.If<HCompareNumericAndBranch>(key, length, Token::LT);
2212 length_checker.Then(); 2213 length_checker.Then();
2213 IfBuilder negative_checker(this); 2214 IfBuilder negative_checker(this);
2214 HValue* bounds_check = negative_checker.If<HCompareNumericAndBranch>( 2215 HValue* bounds_check = negative_checker.If<HCompareNumericAndBranch>(
2215 key, graph()->GetConstant0(), Token::GTE); 2216 key, graph()->GetConstant0(), Token::GTE);
2216 negative_checker.Then(); 2217 negative_checker.Then();
2217 HInstruction* result = AddElementAccess( 2218 HInstruction* result = AddElementAccess(
2218 backing_store, key, val, bounds_check, elements_kind, is_store); 2219 backing_store, key, val, bounds_check, elements_kind, access_type);
2219 negative_checker.ElseDeopt("Negative key encountered"); 2220 negative_checker.ElseDeopt("Negative key encountered");
2220 negative_checker.End(); 2221 negative_checker.End();
2221 length_checker.End(); 2222 length_checker.End();
2222 return result; 2223 return result;
2223 } else { 2224 } else {
2224 ASSERT(store_mode == STANDARD_STORE); 2225 ASSERT(store_mode == STANDARD_STORE);
2225 checked_key = Add<HBoundsCheck>(key, length); 2226 checked_key = Add<HBoundsCheck>(key, length);
2226 return AddElementAccess( 2227 return AddElementAccess(
2227 backing_store, checked_key, val, 2228 backing_store, checked_key, val,
2228 checked_object, elements_kind, is_store); 2229 checked_object, elements_kind, access_type);
2229 } 2230 }
2230 } 2231 }
2231 ASSERT(fast_smi_only_elements || 2232 ASSERT(fast_smi_only_elements ||
2232 fast_elements || 2233 fast_elements ||
2233 IsFastDoubleElementsKind(elements_kind)); 2234 IsFastDoubleElementsKind(elements_kind));
2234 2235
2235 // In case val is stored into a fast smi array, assure that the value is a smi 2236 // In case val is stored into a fast smi array, assure that the value is a smi
2236 // before manipulating the backing store. Otherwise the actual store may 2237 // before manipulating the backing store. Otherwise the actual store may
2237 // deopt, leaving the backing store in an invalid state. 2238 // deopt, leaving the backing store in an invalid state.
2238 if (is_store && IsFastSmiElementsKind(elements_kind) && 2239 if (access_type == STORE && IsFastSmiElementsKind(elements_kind) &&
2239 !val->type().IsSmi()) { 2240 !val->type().IsSmi()) {
2240 val = AddUncasted<HForceRepresentation>(val, Representation::Smi()); 2241 val = AddUncasted<HForceRepresentation>(val, Representation::Smi());
2241 } 2242 }
2242 2243
2243 if (IsGrowStoreMode(store_mode)) { 2244 if (IsGrowStoreMode(store_mode)) {
2244 NoObservableSideEffectsScope no_effects(this); 2245 NoObservableSideEffectsScope no_effects(this);
2245 elements = BuildCheckForCapacityGrow(checked_object, elements, 2246 elements = BuildCheckForCapacityGrow(checked_object, elements,
2246 elements_kind, length, key, 2247 elements_kind, length, key,
2247 is_js_array, is_store); 2248 is_js_array, access_type);
2248 checked_key = key; 2249 checked_key = key;
2249 } else { 2250 } else {
2250 checked_key = Add<HBoundsCheck>(key, length); 2251 checked_key = Add<HBoundsCheck>(key, length);
2251 2252
2252 if (is_store && (fast_elements || fast_smi_only_elements)) { 2253 if (access_type == STORE && (fast_elements || fast_smi_only_elements)) {
2253 if (store_mode == STORE_NO_TRANSITION_HANDLE_COW) { 2254 if (store_mode == STORE_NO_TRANSITION_HANDLE_COW) {
2254 NoObservableSideEffectsScope no_effects(this); 2255 NoObservableSideEffectsScope no_effects(this);
2255 elements = BuildCopyElementsOnWrite(checked_object, elements, 2256 elements = BuildCopyElementsOnWrite(checked_object, elements,
2256 elements_kind, length); 2257 elements_kind, length);
2257 } else { 2258 } else {
2258 HCheckMaps* check_cow_map = Add<HCheckMaps>( 2259 HCheckMaps* check_cow_map = Add<HCheckMaps>(
2259 elements, isolate()->factory()->fixed_array_map(), top_info()); 2260 elements, isolate()->factory()->fixed_array_map(), top_info());
2260 check_cow_map->ClearGVNFlag(kDependsOnElementsKind); 2261 check_cow_map->ClearGVNFlag(kDependsOnElementsKind);
2261 } 2262 }
2262 } 2263 }
2263 } 2264 }
2264 return AddElementAccess(elements, checked_key, val, checked_object, 2265 return AddElementAccess(elements, checked_key, val, checked_object,
2265 elements_kind, is_store, load_mode); 2266 elements_kind, access_type, load_mode);
2266 } 2267 }
2267 2268
2268 2269
2269 2270
2270 HValue* HGraphBuilder::BuildAllocateArrayFromLength( 2271 HValue* HGraphBuilder::BuildAllocateArrayFromLength(
2271 JSArrayBuilder* array_builder, 2272 JSArrayBuilder* array_builder,
2272 HValue* length_argument) { 2273 HValue* length_argument) {
2273 if (length_argument->IsConstant() && 2274 if (length_argument->IsConstant() &&
2274 HConstant::cast(length_argument)->HasSmiValue()) { 2275 HConstant::cast(length_argument)->HasSmiValue()) {
2275 int array_length = HConstant::cast(length_argument)->Integer32Value(); 2276 int array_length = HConstant::cast(length_argument)->Integer32Value();
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after
2397 return elements; 2398 return elements;
2398 } 2399 }
2399 2400
2400 2401
2401 HInstruction* HGraphBuilder::AddElementAccess( 2402 HInstruction* HGraphBuilder::AddElementAccess(
2402 HValue* elements, 2403 HValue* elements,
2403 HValue* checked_key, 2404 HValue* checked_key,
2404 HValue* val, 2405 HValue* val,
2405 HValue* dependency, 2406 HValue* dependency,
2406 ElementsKind elements_kind, 2407 ElementsKind elements_kind,
2407 bool is_store, 2408 PropertyAccessType access_type,
2408 LoadKeyedHoleMode load_mode) { 2409 LoadKeyedHoleMode load_mode) {
2409 if (is_store) { 2410 if (access_type == STORE) {
2410 ASSERT(val != NULL); 2411 ASSERT(val != NULL);
2411 if (elements_kind == EXTERNAL_UINT8_CLAMPED_ELEMENTS || 2412 if (elements_kind == EXTERNAL_UINT8_CLAMPED_ELEMENTS ||
2412 elements_kind == UINT8_CLAMPED_ELEMENTS) { 2413 elements_kind == UINT8_CLAMPED_ELEMENTS) {
2413 val = Add<HClampToUint8>(val); 2414 val = Add<HClampToUint8>(val);
2414 } 2415 }
2415 return Add<HStoreKeyed>(elements, checked_key, val, elements_kind, 2416 return Add<HStoreKeyed>(elements, checked_key, val, elements_kind,
2416 elements_kind == FAST_SMI_ELEMENTS 2417 elements_kind == FAST_SMI_ELEMENTS
2417 ? STORE_TO_INITIALIZED_ENTRY 2418 ? STORE_TO_INITIALIZED_ENTRY
2418 : INITIALIZING_STORE); 2419 : INITIALIZING_STORE);
2419 } 2420 }
2420 2421
2421 ASSERT(!is_store); 2422 ASSERT(access_type == LOAD);
2422 ASSERT(val == NULL); 2423 ASSERT(val == NULL);
2423 HLoadKeyed* load = Add<HLoadKeyed>( 2424 HLoadKeyed* load = Add<HLoadKeyed>(
2424 elements, checked_key, dependency, elements_kind, load_mode); 2425 elements, checked_key, dependency, elements_kind, load_mode);
2425 if (FLAG_opt_safe_uint32_operations && 2426 if (FLAG_opt_safe_uint32_operations &&
2426 (elements_kind == EXTERNAL_UINT32_ELEMENTS || 2427 (elements_kind == EXTERNAL_UINT32_ELEMENTS ||
2427 elements_kind == UINT32_ELEMENTS)) { 2428 elements_kind == UINT32_ELEMENTS)) {
2428 graph()->RecordUint32Instruction(load); 2429 graph()->RecordUint32Instruction(load);
2429 } 2430 }
2430 return load; 2431 return load;
2431 } 2432 }
(...skipping 2343 matching lines...) Expand 10 before | Expand all | Expand 10 after
4775 set_current_block(join); 4776 set_current_block(join);
4776 if (join != NULL && !ast_context()->IsEffect()) { 4777 if (join != NULL && !ast_context()->IsEffect()) {
4777 return ast_context()->ReturnValue(Pop()); 4778 return ast_context()->ReturnValue(Pop());
4778 } 4779 }
4779 } 4780 }
4780 } 4781 }
4781 4782
4782 4783
4783 HOptimizedGraphBuilder::GlobalPropertyAccess 4784 HOptimizedGraphBuilder::GlobalPropertyAccess
4784 HOptimizedGraphBuilder::LookupGlobalProperty( 4785 HOptimizedGraphBuilder::LookupGlobalProperty(
4785 Variable* var, LookupResult* lookup, bool is_store) { 4786 Variable* var, LookupResult* lookup, PropertyAccessType access_type) {
4786 if (var->is_this() || !current_info()->has_global_object()) { 4787 if (var->is_this() || !current_info()->has_global_object()) {
4787 return kUseGeneric; 4788 return kUseGeneric;
4788 } 4789 }
4789 Handle<GlobalObject> global(current_info()->global_object()); 4790 Handle<GlobalObject> global(current_info()->global_object());
4790 global->Lookup(*var->name(), lookup); 4791 global->Lookup(*var->name(), lookup);
4791 if (!lookup->IsNormal() || 4792 if (!lookup->IsNormal() ||
4792 (is_store && lookup->IsReadOnly()) || 4793 (access_type == STORE && lookup->IsReadOnly()) ||
4793 lookup->holder() != *global) { 4794 lookup->holder() != *global) {
4794 return kUseGeneric; 4795 return kUseGeneric;
4795 } 4796 }
4796 4797
4797 return kUseCell; 4798 return kUseCell;
4798 } 4799 }
4799 4800
4800 4801
4801 HValue* HOptimizedGraphBuilder::BuildContextChainWalk(Variable* var) { 4802 HValue* HOptimizedGraphBuilder::BuildContextChainWalk(Variable* var) {
4802 ASSERT(var->IsContextSlot()); 4803 ASSERT(var->IsContextSlot());
(...skipping 25 matching lines...) Expand all
4828 // Handle known global constants like 'undefined' specially to avoid a 4829 // Handle known global constants like 'undefined' specially to avoid a
4829 // load from a global cell for them. 4830 // load from a global cell for them.
4830 Handle<Object> constant_value = 4831 Handle<Object> constant_value =
4831 isolate()->factory()->GlobalConstantFor(variable->name()); 4832 isolate()->factory()->GlobalConstantFor(variable->name());
4832 if (!constant_value.is_null()) { 4833 if (!constant_value.is_null()) {
4833 HConstant* instr = New<HConstant>(constant_value); 4834 HConstant* instr = New<HConstant>(constant_value);
4834 return ast_context()->ReturnInstruction(instr, expr->id()); 4835 return ast_context()->ReturnInstruction(instr, expr->id());
4835 } 4836 }
4836 4837
4837 LookupResult lookup(isolate()); 4838 LookupResult lookup(isolate());
4838 GlobalPropertyAccess type = 4839 GlobalPropertyAccess type = LookupGlobalProperty(variable, &lookup, LOAD);
4839 LookupGlobalProperty(variable, &lookup, false);
4840 4840
4841 if (type == kUseCell && 4841 if (type == kUseCell &&
4842 current_info()->global_object()->IsAccessCheckNeeded()) { 4842 current_info()->global_object()->IsAccessCheckNeeded()) {
4843 type = kUseGeneric; 4843 type = kUseGeneric;
4844 } 4844 }
4845 4845
4846 if (type == kUseCell) { 4846 if (type == kUseCell) {
4847 Handle<GlobalObject> global(current_info()->global_object()); 4847 Handle<GlobalObject> global(current_info()->global_object());
4848 Handle<PropertyCell> cell(global->GetPropertyCell(&lookup)); 4848 Handle<PropertyCell> cell(global->GetPropertyCell(&lookup));
4849 if (cell->type()->IsConstant()) { 4849 if (cell->type()->IsConstant()) {
(...skipping 894 matching lines...) Expand 10 before | Expand all | Expand 10 after
5744 BailoutId ast_id, 5744 BailoutId ast_id,
5745 BailoutId return_id, 5745 BailoutId return_id,
5746 bool is_uninitialized) { 5746 bool is_uninitialized) {
5747 if (!prop->key()->IsPropertyName()) { 5747 if (!prop->key()->IsPropertyName()) {
5748 // Keyed store. 5748 // Keyed store.
5749 HValue* value = environment()->ExpressionStackAt(0); 5749 HValue* value = environment()->ExpressionStackAt(0);
5750 HValue* key = environment()->ExpressionStackAt(1); 5750 HValue* key = environment()->ExpressionStackAt(1);
5751 HValue* object = environment()->ExpressionStackAt(2); 5751 HValue* object = environment()->ExpressionStackAt(2);
5752 bool has_side_effects = false; 5752 bool has_side_effects = false;
5753 HandleKeyedElementAccess(object, key, value, expr, 5753 HandleKeyedElementAccess(object, key, value, expr,
5754 true, // is_store 5754 STORE, &has_side_effects);
5755 &has_side_effects);
5756 Drop(3); 5755 Drop(3);
5757 Push(value); 5756 Push(value);
5758 Add<HSimulate>(return_id, REMOVABLE_SIMULATE); 5757 Add<HSimulate>(return_id, REMOVABLE_SIMULATE);
5759 return ast_context()->ReturnValue(Pop()); 5758 return ast_context()->ReturnValue(Pop());
5760 } 5759 }
5761 5760
5762 // Named store. 5761 // Named store.
5763 HValue* value = Pop(); 5762 HValue* value = Pop();
5764 HValue* object = Pop(); 5763 HValue* object = Pop();
5765 5764
(...skipping 29 matching lines...) Expand all
5795 5794
5796 5795
5797 // Because not every expression has a position and there is not common 5796 // Because not every expression has a position and there is not common
5798 // superclass of Assignment and CountOperation, we cannot just pass the 5797 // superclass of Assignment and CountOperation, we cannot just pass the
5799 // owning expression instead of position and ast_id separately. 5798 // owning expression instead of position and ast_id separately.
5800 void HOptimizedGraphBuilder::HandleGlobalVariableAssignment( 5799 void HOptimizedGraphBuilder::HandleGlobalVariableAssignment(
5801 Variable* var, 5800 Variable* var,
5802 HValue* value, 5801 HValue* value,
5803 BailoutId ast_id) { 5802 BailoutId ast_id) {
5804 LookupResult lookup(isolate()); 5803 LookupResult lookup(isolate());
5805 GlobalPropertyAccess type = LookupGlobalProperty(var, &lookup, true); 5804 GlobalPropertyAccess type = LookupGlobalProperty(var, &lookup, STORE);
5806 if (type == kUseCell) { 5805 if (type == kUseCell) {
5807 Handle<GlobalObject> global(current_info()->global_object()); 5806 Handle<GlobalObject> global(current_info()->global_object());
5808 Handle<PropertyCell> cell(global->GetPropertyCell(&lookup)); 5807 Handle<PropertyCell> cell(global->GetPropertyCell(&lookup));
5809 if (cell->type()->IsConstant()) { 5808 if (cell->type()->IsConstant()) {
5810 IfBuilder builder(this); 5809 IfBuilder builder(this);
5811 HValue* constant = Add<HConstant>(cell->type()->AsConstant()); 5810 HValue* constant = Add<HConstant>(cell->type()->AsConstant());
5812 if (cell->type()->AsConstant()->IsNumber()) { 5811 if (cell->type()->AsConstant()->IsNumber()) {
5813 builder.If<HCompareNumericAndBranch>(value, constant, Token::EQ); 5812 builder.If<HCompareNumericAndBranch>(value, constant, Token::EQ);
5814 } else { 5813 } else {
5815 builder.If<HCompareObjectEqAndBranch>(value, constant); 5814 builder.If<HCompareObjectEqAndBranch>(value, constant);
(...skipping 373 matching lines...) Expand 10 before | Expand all | Expand 10 after
6189 return load_mode; 6188 return load_mode;
6190 } 6189 }
6191 6190
6192 6191
6193 HInstruction* HOptimizedGraphBuilder::BuildMonomorphicElementAccess( 6192 HInstruction* HOptimizedGraphBuilder::BuildMonomorphicElementAccess(
6194 HValue* object, 6193 HValue* object,
6195 HValue* key, 6194 HValue* key,
6196 HValue* val, 6195 HValue* val,
6197 HValue* dependency, 6196 HValue* dependency,
6198 Handle<Map> map, 6197 Handle<Map> map,
6199 bool is_store, 6198 PropertyAccessType access_type,
6200 KeyedAccessStoreMode store_mode) { 6199 KeyedAccessStoreMode store_mode) {
6201 HCheckMaps* checked_object = Add<HCheckMaps>(object, map, top_info(), 6200 HCheckMaps* checked_object = Add<HCheckMaps>(object, map, top_info(),
6202 dependency); 6201 dependency);
6203 if (dependency) { 6202 if (dependency) {
6204 checked_object->ClearGVNFlag(kDependsOnElementsKind); 6203 checked_object->ClearGVNFlag(kDependsOnElementsKind);
6205 } 6204 }
6206 6205
6207 if (is_store && map->prototype()->IsJSObject()) { 6206 if (access_type == STORE && map->prototype()->IsJSObject()) {
6208 // monomorphic stores need a prototype chain check because shape 6207 // monomorphic stores need a prototype chain check because shape
6209 // changes could allow callbacks on elements in the chain that 6208 // changes could allow callbacks on elements in the chain that
6210 // aren't compatible with monomorphic keyed stores. 6209 // aren't compatible with monomorphic keyed stores.
6211 Handle<JSObject> prototype(JSObject::cast(map->prototype())); 6210 Handle<JSObject> prototype(JSObject::cast(map->prototype()));
6212 Object* holder = map->prototype(); 6211 Object* holder = map->prototype();
6213 while (holder->GetPrototype(isolate())->IsJSObject()) { 6212 while (holder->GetPrototype(isolate())->IsJSObject()) {
6214 holder = holder->GetPrototype(isolate()); 6213 holder = holder->GetPrototype(isolate());
6215 } 6214 }
6216 ASSERT(holder->GetPrototype(isolate())->IsNull()); 6215 ASSERT(holder->GetPrototype(isolate())->IsNull());
6217 6216
6218 BuildCheckPrototypeMaps(prototype, 6217 BuildCheckPrototypeMaps(prototype,
6219 Handle<JSObject>(JSObject::cast(holder))); 6218 Handle<JSObject>(JSObject::cast(holder)));
6220 } 6219 }
6221 6220
6222 LoadKeyedHoleMode load_mode = BuildKeyedHoleMode(map); 6221 LoadKeyedHoleMode load_mode = BuildKeyedHoleMode(map);
6223 return BuildUncheckedMonomorphicElementAccess( 6222 return BuildUncheckedMonomorphicElementAccess(
6224 checked_object, key, val, 6223 checked_object, key, val,
6225 map->instance_type() == JS_ARRAY_TYPE, 6224 map->instance_type() == JS_ARRAY_TYPE,
6226 map->elements_kind(), is_store, 6225 map->elements_kind(), access_type,
6227 load_mode, store_mode); 6226 load_mode, store_mode);
6228 } 6227 }
6229 6228
6230 6229
6231 HInstruction* HOptimizedGraphBuilder::TryBuildConsolidatedElementLoad( 6230 HInstruction* HOptimizedGraphBuilder::TryBuildConsolidatedElementLoad(
6232 HValue* object, 6231 HValue* object,
6233 HValue* key, 6232 HValue* key,
6234 HValue* val, 6233 HValue* val,
6235 SmallMapList* maps) { 6234 SmallMapList* maps) {
6236 // For polymorphic loads of similar elements kinds (i.e. all tagged or all 6235 // For polymorphic loads of similar elements kinds (i.e. all tagged or all
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
6282 HCheckMaps* checked_object = Add<HCheckMaps>(object, maps); 6281 HCheckMaps* checked_object = Add<HCheckMaps>(object, maps);
6283 // FAST_ELEMENTS is considered more general than FAST_HOLEY_SMI_ELEMENTS. 6282 // FAST_ELEMENTS is considered more general than FAST_HOLEY_SMI_ELEMENTS.
6284 // If we've seen both, the consolidated load must use FAST_HOLEY_ELEMENTS. 6283 // If we've seen both, the consolidated load must use FAST_HOLEY_ELEMENTS.
6285 ElementsKind consolidated_elements_kind = has_seen_holey_elements 6284 ElementsKind consolidated_elements_kind = has_seen_holey_elements
6286 ? GetHoleyElementsKind(most_general_consolidated_map->elements_kind()) 6285 ? GetHoleyElementsKind(most_general_consolidated_map->elements_kind())
6287 : most_general_consolidated_map->elements_kind(); 6286 : most_general_consolidated_map->elements_kind();
6288 HInstruction* instr = BuildUncheckedMonomorphicElementAccess( 6287 HInstruction* instr = BuildUncheckedMonomorphicElementAccess(
6289 checked_object, key, val, 6288 checked_object, key, val,
6290 most_general_consolidated_map->instance_type() == JS_ARRAY_TYPE, 6289 most_general_consolidated_map->instance_type() == JS_ARRAY_TYPE,
6291 consolidated_elements_kind, 6290 consolidated_elements_kind,
6292 false, NEVER_RETURN_HOLE, STANDARD_STORE); 6291 LOAD, NEVER_RETURN_HOLE, STANDARD_STORE);
6293 return instr; 6292 return instr;
6294 } 6293 }
6295 6294
6296 6295
6297 HValue* HOptimizedGraphBuilder::HandlePolymorphicElementAccess( 6296 HValue* HOptimizedGraphBuilder::HandlePolymorphicElementAccess(
6298 HValue* object, 6297 HValue* object,
6299 HValue* key, 6298 HValue* key,
6300 HValue* val, 6299 HValue* val,
6301 SmallMapList* maps, 6300 SmallMapList* maps,
6302 bool is_store, 6301 PropertyAccessType access_type,
6303 KeyedAccessStoreMode store_mode, 6302 KeyedAccessStoreMode store_mode,
6304 bool* has_side_effects) { 6303 bool* has_side_effects) {
6305 *has_side_effects = false; 6304 *has_side_effects = false;
6306 BuildCheckHeapObject(object); 6305 BuildCheckHeapObject(object);
6307 6306
6308 if (!is_store) { 6307 if (access_type == LOAD) {
6309 HInstruction* consolidated_load = 6308 HInstruction* consolidated_load =
6310 TryBuildConsolidatedElementLoad(object, key, val, maps); 6309 TryBuildConsolidatedElementLoad(object, key, val, maps);
6311 if (consolidated_load != NULL) { 6310 if (consolidated_load != NULL) {
6312 *has_side_effects |= consolidated_load->HasObservableSideEffects(); 6311 *has_side_effects |= consolidated_load->HasObservableSideEffects();
6313 return consolidated_load; 6312 return consolidated_load;
6314 } 6313 }
6315 } 6314 }
6316 6315
6317 // Elements_kind transition support. 6316 // Elements_kind transition support.
6318 MapHandleList transition_target(maps->length()); 6317 MapHandleList transition_target(maps->length());
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
6351 } 6350 }
6352 6351
6353 // If only one map is left after transitioning, handle this case 6352 // If only one map is left after transitioning, handle this case
6354 // monomorphically. 6353 // monomorphically.
6355 ASSERT(untransitionable_maps.length() >= 1); 6354 ASSERT(untransitionable_maps.length() >= 1);
6356 if (untransitionable_maps.length() == 1) { 6355 if (untransitionable_maps.length() == 1) {
6357 Handle<Map> untransitionable_map = untransitionable_maps[0]; 6356 Handle<Map> untransitionable_map = untransitionable_maps[0];
6358 HInstruction* instr = NULL; 6357 HInstruction* instr = NULL;
6359 if (untransitionable_map->has_slow_elements_kind() || 6358 if (untransitionable_map->has_slow_elements_kind() ||
6360 !untransitionable_map->IsJSObjectMap()) { 6359 !untransitionable_map->IsJSObjectMap()) {
6361 instr = AddInstruction(is_store ? BuildStoreKeyedGeneric(object, key, val) 6360 instr = AddInstruction(access_type == STORE
6362 : BuildLoadKeyedGeneric(object, key)); 6361 ? BuildStoreKeyedGeneric(object, key, val)
6362 : BuildLoadKeyedGeneric(object, key));
6363 } else { 6363 } else {
6364 instr = BuildMonomorphicElementAccess( 6364 instr = BuildMonomorphicElementAccess(
6365 object, key, val, transition, untransitionable_map, is_store, 6365 object, key, val, transition, untransitionable_map, access_type,
6366 store_mode); 6366 store_mode);
6367 } 6367 }
6368 *has_side_effects |= instr->HasObservableSideEffects(); 6368 *has_side_effects |= instr->HasObservableSideEffects();
6369 return is_store ? NULL : instr; 6369 return access_type == STORE ? NULL : instr;
6370 } 6370 }
6371 6371
6372 HBasicBlock* join = graph()->CreateBasicBlock(); 6372 HBasicBlock* join = graph()->CreateBasicBlock();
6373 6373
6374 for (int i = 0; i < untransitionable_maps.length(); ++i) { 6374 for (int i = 0; i < untransitionable_maps.length(); ++i) {
6375 Handle<Map> map = untransitionable_maps[i]; 6375 Handle<Map> map = untransitionable_maps[i];
6376 if (!map->IsJSObjectMap()) continue; 6376 if (!map->IsJSObjectMap()) continue;
6377 ElementsKind elements_kind = map->elements_kind(); 6377 ElementsKind elements_kind = map->elements_kind();
6378 HBasicBlock* this_map = graph()->CreateBasicBlock(); 6378 HBasicBlock* this_map = graph()->CreateBasicBlock();
6379 HBasicBlock* other_map = graph()->CreateBasicBlock(); 6379 HBasicBlock* other_map = graph()->CreateBasicBlock();
6380 HCompareMap* mapcompare = 6380 HCompareMap* mapcompare =
6381 New<HCompareMap>(object, map, this_map, other_map); 6381 New<HCompareMap>(object, map, this_map, other_map);
6382 FinishCurrentBlock(mapcompare); 6382 FinishCurrentBlock(mapcompare);
6383 6383
6384 set_current_block(this_map); 6384 set_current_block(this_map);
6385 HInstruction* access = NULL; 6385 HInstruction* access = NULL;
6386 if (IsDictionaryElementsKind(elements_kind)) { 6386 if (IsDictionaryElementsKind(elements_kind)) {
6387 access = is_store 6387 access = access_type == STORE
6388 ? AddInstruction(BuildStoreKeyedGeneric(object, key, val)) 6388 ? AddInstruction(BuildStoreKeyedGeneric(object, key, val))
6389 : AddInstruction(BuildLoadKeyedGeneric(object, key)); 6389 : AddInstruction(BuildLoadKeyedGeneric(object, key));
6390 } else { 6390 } else {
6391 ASSERT(IsFastElementsKind(elements_kind) || 6391 ASSERT(IsFastElementsKind(elements_kind) ||
6392 IsExternalArrayElementsKind(elements_kind)); 6392 IsExternalArrayElementsKind(elements_kind));
6393 LoadKeyedHoleMode load_mode = BuildKeyedHoleMode(map); 6393 LoadKeyedHoleMode load_mode = BuildKeyedHoleMode(map);
6394 // Happily, mapcompare is a checked object. 6394 // Happily, mapcompare is a checked object.
6395 access = BuildUncheckedMonomorphicElementAccess( 6395 access = BuildUncheckedMonomorphicElementAccess(
6396 mapcompare, key, val, 6396 mapcompare, key, val,
6397 map->instance_type() == JS_ARRAY_TYPE, 6397 map->instance_type() == JS_ARRAY_TYPE,
6398 elements_kind, is_store, 6398 elements_kind, access_type,
6399 load_mode, 6399 load_mode,
6400 store_mode); 6400 store_mode);
6401 } 6401 }
6402 *has_side_effects |= access->HasObservableSideEffects(); 6402 *has_side_effects |= access->HasObservableSideEffects();
6403 // The caller will use has_side_effects and add a correct Simulate. 6403 // The caller will use has_side_effects and add a correct Simulate.
6404 access->SetFlag(HValue::kHasNoObservableSideEffects); 6404 access->SetFlag(HValue::kHasNoObservableSideEffects);
6405 if (!is_store) { 6405 if (access_type == LOAD) {
6406 Push(access); 6406 Push(access);
6407 } 6407 }
6408 NoObservableSideEffectsScope scope(this); 6408 NoObservableSideEffectsScope scope(this);
6409 GotoNoSimulate(join); 6409 GotoNoSimulate(join);
6410 set_current_block(other_map); 6410 set_current_block(other_map);
6411 } 6411 }
6412 6412
6413 // Deopt if none of the cases matched. 6413 // Deopt if none of the cases matched.
6414 NoObservableSideEffectsScope scope(this); 6414 NoObservableSideEffectsScope scope(this);
6415 FinishExitWithHardDeoptimization("Unknown map in polymorphic element access", 6415 FinishExitWithHardDeoptimization("Unknown map in polymorphic element access",
6416 join); 6416 join);
6417 set_current_block(join); 6417 set_current_block(join);
6418 return is_store ? NULL : Pop(); 6418 return access_type == STORE ? NULL : Pop();
6419 } 6419 }
6420 6420
6421 6421
6422 HValue* HOptimizedGraphBuilder::HandleKeyedElementAccess( 6422 HValue* HOptimizedGraphBuilder::HandleKeyedElementAccess(
6423 HValue* obj, 6423 HValue* obj,
6424 HValue* key, 6424 HValue* key,
6425 HValue* val, 6425 HValue* val,
6426 Expression* expr, 6426 Expression* expr,
6427 bool is_store, 6427 PropertyAccessType access_type,
6428 bool* has_side_effects) { 6428 bool* has_side_effects) {
6429 ASSERT(!expr->IsPropertyName()); 6429 ASSERT(!expr->IsPropertyName());
6430 HInstruction* instr = NULL; 6430 HInstruction* instr = NULL;
6431 6431
6432 SmallMapList* types; 6432 SmallMapList* types;
6433 bool monomorphic = ComputeReceiverTypes(expr, obj, &types, zone()); 6433 bool monomorphic = ComputeReceiverTypes(expr, obj, &types, zone());
6434 6434
6435 bool force_generic = false; 6435 bool force_generic = false;
6436 if (is_store && (monomorphic || (types != NULL && !types->is_empty()))) { 6436 if (access_type == STORE &&
6437 (monomorphic || (types != NULL && !types->is_empty()))) {
6437 // Stores can't be mono/polymorphic if their prototype chain has dictionary 6438 // Stores can't be mono/polymorphic if their prototype chain has dictionary
6438 // elements. However a receiver map that has dictionary elements itself 6439 // elements. However a receiver map that has dictionary elements itself
6439 // should be left to normal mono/poly behavior (the other maps may benefit 6440 // should be left to normal mono/poly behavior (the other maps may benefit
6440 // from highly optimized stores). 6441 // from highly optimized stores).
6441 for (int i = 0; i < types->length(); i++) { 6442 for (int i = 0; i < types->length(); i++) {
6442 Handle<Map> current_map = types->at(i); 6443 Handle<Map> current_map = types->at(i);
6443 if (current_map->DictionaryElementsInPrototypeChainOnly()) { 6444 if (current_map->DictionaryElementsInPrototypeChainOnly()) {
6444 force_generic = true; 6445 force_generic = true;
6445 monomorphic = false; 6446 monomorphic = false;
6446 break; 6447 break;
6447 } 6448 }
6448 } 6449 }
6449 } 6450 }
6450 6451
6451 if (monomorphic) { 6452 if (monomorphic) {
6452 Handle<Map> map = types->first(); 6453 Handle<Map> map = types->first();
6453 if (map->has_slow_elements_kind() || !map->IsJSObjectMap()) { 6454 if (map->has_slow_elements_kind() || !map->IsJSObjectMap()) {
6454 instr = is_store ? BuildStoreKeyedGeneric(obj, key, val) 6455 instr = access_type == STORE
6455 : BuildLoadKeyedGeneric(obj, key); 6456 ? BuildStoreKeyedGeneric(obj, key, val)
6457 : BuildLoadKeyedGeneric(obj, key);
6456 AddInstruction(instr); 6458 AddInstruction(instr);
6457 } else { 6459 } else {
6458 BuildCheckHeapObject(obj); 6460 BuildCheckHeapObject(obj);
6459 instr = BuildMonomorphicElementAccess( 6461 instr = BuildMonomorphicElementAccess(
6460 obj, key, val, NULL, map, is_store, expr->GetStoreMode()); 6462 obj, key, val, NULL, map, access_type, expr->GetStoreMode());
6461 } 6463 }
6462 } else if (!force_generic && (types != NULL && !types->is_empty())) { 6464 } else if (!force_generic && (types != NULL && !types->is_empty())) {
6463 return HandlePolymorphicElementAccess( 6465 return HandlePolymorphicElementAccess(
6464 obj, key, val, types, is_store, 6466 obj, key, val, types, access_type,
6465 expr->GetStoreMode(), has_side_effects); 6467 expr->GetStoreMode(), has_side_effects);
6466 } else { 6468 } else {
6467 if (is_store) { 6469 if (access_type == STORE) {
6468 if (expr->IsAssignment() && 6470 if (expr->IsAssignment() &&
6469 expr->AsAssignment()->HasNoTypeInformation()) { 6471 expr->AsAssignment()->HasNoTypeInformation()) {
6470 Add<HDeoptimize>("Insufficient type feedback for keyed store", 6472 Add<HDeoptimize>("Insufficient type feedback for keyed store",
6471 Deoptimizer::SOFT); 6473 Deoptimizer::SOFT);
6472 } 6474 }
6473 instr = BuildStoreKeyedGeneric(obj, key, val); 6475 instr = BuildStoreKeyedGeneric(obj, key, val);
6474 } else { 6476 } else {
6475 if (expr->AsProperty()->HasNoTypeInformation()) { 6477 if (expr->AsProperty()->HasNoTypeInformation()) {
6476 Add<HDeoptimize>("Insufficient type feedback for keyed load", 6478 Add<HDeoptimize>("Insufficient type feedback for keyed load",
6477 Deoptimizer::SOFT); 6479 Deoptimizer::SOFT);
(...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after
6646 object, name, NULL, expr->IsUninitialized()); 6648 object, name, NULL, expr->IsUninitialized());
6647 if (instr == NULL) return; 6649 if (instr == NULL) return;
6648 if (instr->IsLinked()) return ast_context()->ReturnValue(instr); 6650 if (instr->IsLinked()) return ast_context()->ReturnValue(instr);
6649 6651
6650 } else { 6652 } else {
6651 HValue* key = Pop(); 6653 HValue* key = Pop();
6652 HValue* obj = Pop(); 6654 HValue* obj = Pop();
6653 6655
6654 bool has_side_effects = false; 6656 bool has_side_effects = false;
6655 HValue* load = HandleKeyedElementAccess( 6657 HValue* load = HandleKeyedElementAccess(
6656 obj, key, NULL, expr, 6658 obj, key, NULL, expr, LOAD, &has_side_effects);
6657 false, // is_store
6658 &has_side_effects);
6659 if (has_side_effects) { 6659 if (has_side_effects) {
6660 if (ast_context()->IsEffect()) { 6660 if (ast_context()->IsEffect()) {
6661 Add<HSimulate>(ast_id, REMOVABLE_SIMULATE); 6661 Add<HSimulate>(ast_id, REMOVABLE_SIMULATE);
6662 } else { 6662 } else {
6663 Push(load); 6663 Push(load);
6664 Add<HSimulate>(ast_id, REMOVABLE_SIMULATE); 6664 Add<HSimulate>(ast_id, REMOVABLE_SIMULATE);
6665 Drop(1); 6665 Drop(1);
6666 } 6666 }
6667 } 6667 }
6668 return ast_context()->ReturnValue(load); 6668 return ast_context()->ReturnValue(load);
(...skipping 908 matching lines...) Expand 10 before | Expand all | Expand 10 after
7577 7577
7578 length_checker.Else(); 7578 length_checker.Else();
7579 HValue* elements = AddLoadElements(checked_object); 7579 HValue* elements = AddLoadElements(checked_object);
7580 // Ensure that we aren't popping from a copy-on-write array. 7580 // Ensure that we aren't popping from a copy-on-write array.
7581 if (IsFastSmiOrObjectElementsKind(elements_kind)) { 7581 if (IsFastSmiOrObjectElementsKind(elements_kind)) {
7582 elements = BuildCopyElementsOnWrite(checked_object, elements, 7582 elements = BuildCopyElementsOnWrite(checked_object, elements,
7583 elements_kind, length); 7583 elements_kind, length);
7584 } 7584 }
7585 reduced_length = AddUncasted<HSub>(length, graph()->GetConstant1()); 7585 reduced_length = AddUncasted<HSub>(length, graph()->GetConstant1());
7586 result = AddElementAccess(elements, reduced_length, NULL, 7586 result = AddElementAccess(elements, reduced_length, NULL,
7587 bounds_check, elements_kind, false); 7587 bounds_check, elements_kind, LOAD);
7588 Factory* factory = isolate()->factory(); 7588 Factory* factory = isolate()->factory();
7589 double nan_double = FixedDoubleArray::hole_nan_as_double(); 7589 double nan_double = FixedDoubleArray::hole_nan_as_double();
7590 HValue* hole = IsFastSmiOrObjectElementsKind(elements_kind) 7590 HValue* hole = IsFastSmiOrObjectElementsKind(elements_kind)
7591 ? Add<HConstant>(factory->the_hole_value()) 7591 ? Add<HConstant>(factory->the_hole_value())
7592 : Add<HConstant>(nan_double); 7592 : Add<HConstant>(nan_double);
7593 if (IsFastSmiOrObjectElementsKind(elements_kind)) { 7593 if (IsFastSmiOrObjectElementsKind(elements_kind)) {
7594 elements_kind = FAST_HOLEY_ELEMENTS; 7594 elements_kind = FAST_HOLEY_ELEMENTS;
7595 } 7595 }
7596 AddElementAccess( 7596 AddElementAccess(
7597 elements, reduced_length, hole, bounds_check, elements_kind, true); 7597 elements, reduced_length, hole, bounds_check, elements_kind, STORE);
7598 Add<HStoreNamedField>( 7598 Add<HStoreNamedField>(
7599 checked_object, HObjectAccess::ForArrayLength(elements_kind), 7599 checked_object, HObjectAccess::ForArrayLength(elements_kind),
7600 reduced_length, STORE_TO_INITIALIZED_ENTRY); 7600 reduced_length, STORE_TO_INITIALIZED_ENTRY);
7601 7601
7602 if (!ast_context()->IsEffect()) Push(result); 7602 if (!ast_context()->IsEffect()) Push(result);
7603 7603
7604 length_checker.End(); 7604 length_checker.End();
7605 } 7605 }
7606 result = ast_context()->IsEffect() ? graph()->GetConstant0() : Top(); 7606 result = ast_context()->IsEffect() ? graph()->GetConstant0() : Top();
7607 Add<HSimulate>(expr->id(), REMOVABLE_SIMULATE); 7607 Add<HSimulate>(expr->id(), REMOVABLE_SIMULATE);
(...skipping 395 matching lines...) Expand 10 before | Expand all | Expand 10 after
8003 } 8003 }
8004 8004
8005 bool global_call = proxy != NULL && proxy->var()->IsUnallocated(); 8005 bool global_call = proxy != NULL && proxy->var()->IsUnallocated();
8006 if (global_call) { 8006 if (global_call) {
8007 Variable* var = proxy->var(); 8007 Variable* var = proxy->var();
8008 bool known_global_function = false; 8008 bool known_global_function = false;
8009 // If there is a global property cell for the name at compile time and 8009 // If there is a global property cell for the name at compile time and
8010 // access check is not enabled we assume that the function will not change 8010 // access check is not enabled we assume that the function will not change
8011 // and generate optimized code for calling the function. 8011 // and generate optimized code for calling the function.
8012 LookupResult lookup(isolate()); 8012 LookupResult lookup(isolate());
8013 GlobalPropertyAccess type = LookupGlobalProperty(var, &lookup, false); 8013 GlobalPropertyAccess type = LookupGlobalProperty(var, &lookup, LOAD);
8014 if (type == kUseCell && 8014 if (type == kUseCell &&
8015 !current_info()->global_object()->IsAccessCheckNeeded()) { 8015 !current_info()->global_object()->IsAccessCheckNeeded()) {
8016 Handle<GlobalObject> global(current_info()->global_object()); 8016 Handle<GlobalObject> global(current_info()->global_object());
8017 known_global_function = expr->ComputeGlobalTarget(global, &lookup); 8017 known_global_function = expr->ComputeGlobalTarget(global, &lookup);
8018 } 8018 }
8019 CHECK_ALIVE(VisitForValue(expr->expression())); 8019 CHECK_ALIVE(VisitForValue(expr->expression()));
8020 HValue* function = Top(); 8020 HValue* function = Top();
8021 if (known_global_function) { 8021 if (known_global_function) {
8022 Add<HCheckValue>(function, expr->target()); 8022 Add<HCheckValue>(function, expr->target());
8023 8023
(...skipping 3184 matching lines...) Expand 10 before | Expand all | Expand 10 after
11208 if (ShouldProduceTraceOutput()) { 11208 if (ShouldProduceTraceOutput()) {
11209 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); 11209 isolate()->GetHTracer()->TraceHydrogen(name(), graph_);
11210 } 11210 }
11211 11211
11212 #ifdef DEBUG 11212 #ifdef DEBUG
11213 graph_->Verify(false); // No full verify. 11213 graph_->Verify(false); // No full verify.
11214 #endif 11214 #endif
11215 } 11215 }
11216 11216
11217 } } // namespace v8::internal 11217 } } // 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