Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 6149 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 6160 if (access_type == LOAD) { | 6160 if (access_type == LOAD) { |
| 6161 return New<HLoadNamedGeneric>(object, name); | 6161 return New<HLoadNamedGeneric>(object, name); |
| 6162 } else { | 6162 } else { |
| 6163 return New<HStoreNamedGeneric>( | 6163 return New<HStoreNamedGeneric>( |
| 6164 object, name, value, function_strict_mode_flag()); | 6164 object, name, value, function_strict_mode_flag()); |
| 6165 } | 6165 } |
| 6166 } | 6166 } |
| 6167 | 6167 |
| 6168 | 6168 |
| 6169 | 6169 |
| 6170 HInstruction* HOptimizedGraphBuilder::BuildLoadKeyedGeneric(HValue* object, | 6170 HInstruction* HOptimizedGraphBuilder::BuildKeyedGeneric( |
| 6171 HValue* key) { | 6171 PropertyAccessType access_type, |
| 6172 return New<HLoadKeyedGeneric>(object, key); | 6172 HValue* object, |
| 6173 HValue* key, | |
| 6174 HValue* value) { | |
| 6175 if (access_type == LOAD) { | |
| 6176 return New<HLoadKeyedGeneric>(object, key); | |
| 6177 } else { | |
|
tfarina
2014/02/10 15:01:29
no 'else' after return.
you can also use a ternay
Sven Panne
2014/02/11 07:08:36
Although I am a big fan of "comb-like" control flo
| |
| 6178 return New<HStoreKeyedGeneric>( | |
| 6179 object, key, value, function_strict_mode_flag()); | |
| 6180 } | |
| 6173 } | 6181 } |
| 6174 | 6182 |
| 6175 | 6183 |
| 6176 LoadKeyedHoleMode HOptimizedGraphBuilder::BuildKeyedHoleMode(Handle<Map> map) { | 6184 LoadKeyedHoleMode HOptimizedGraphBuilder::BuildKeyedHoleMode(Handle<Map> map) { |
| 6177 // Loads from a "stock" fast holey double arrays can elide the hole check. | 6185 // Loads from a "stock" fast holey double arrays can elide the hole check. |
| 6178 LoadKeyedHoleMode load_mode = NEVER_RETURN_HOLE; | 6186 LoadKeyedHoleMode load_mode = NEVER_RETURN_HOLE; |
| 6179 if (*map == isolate()->get_initial_js_array_map(FAST_HOLEY_DOUBLE_ELEMENTS) && | 6187 if (*map == isolate()->get_initial_js_array_map(FAST_HOLEY_DOUBLE_ELEMENTS) && |
| 6180 isolate()->IsFastArrayConstructorPrototypeChainIntact()) { | 6188 isolate()->IsFastArrayConstructorPrototypeChainIntact()) { |
| 6181 Handle<JSObject> prototype(JSObject::cast(map->prototype()), isolate()); | 6189 Handle<JSObject> prototype(JSObject::cast(map->prototype()), isolate()); |
| 6182 Handle<JSObject> object_prototype = isolate()->initial_object_prototype(); | 6190 Handle<JSObject> object_prototype = isolate()->initial_object_prototype(); |
| (...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 6350 } | 6358 } |
| 6351 | 6359 |
| 6352 // If only one map is left after transitioning, handle this case | 6360 // If only one map is left after transitioning, handle this case |
| 6353 // monomorphically. | 6361 // monomorphically. |
| 6354 ASSERT(untransitionable_maps.length() >= 1); | 6362 ASSERT(untransitionable_maps.length() >= 1); |
| 6355 if (untransitionable_maps.length() == 1) { | 6363 if (untransitionable_maps.length() == 1) { |
| 6356 Handle<Map> untransitionable_map = untransitionable_maps[0]; | 6364 Handle<Map> untransitionable_map = untransitionable_maps[0]; |
| 6357 HInstruction* instr = NULL; | 6365 HInstruction* instr = NULL; |
| 6358 if (untransitionable_map->has_slow_elements_kind() || | 6366 if (untransitionable_map->has_slow_elements_kind() || |
| 6359 !untransitionable_map->IsJSObjectMap()) { | 6367 !untransitionable_map->IsJSObjectMap()) { |
| 6360 instr = AddInstruction(access_type == STORE | 6368 instr = AddInstruction(BuildKeyedGeneric(access_type, object, key, val)); |
| 6361 ? BuildStoreKeyedGeneric(object, key, val) | |
| 6362 : BuildLoadKeyedGeneric(object, key)); | |
| 6363 } else { | 6369 } else { |
| 6364 instr = BuildMonomorphicElementAccess( | 6370 instr = BuildMonomorphicElementAccess( |
| 6365 object, key, val, transition, untransitionable_map, access_type, | 6371 object, key, val, transition, untransitionable_map, access_type, |
| 6366 store_mode); | 6372 store_mode); |
| 6367 } | 6373 } |
| 6368 *has_side_effects |= instr->HasObservableSideEffects(); | 6374 *has_side_effects |= instr->HasObservableSideEffects(); |
| 6369 return access_type == STORE ? NULL : instr; | 6375 return access_type == STORE ? NULL : instr; |
| 6370 } | 6376 } |
| 6371 | 6377 |
| 6372 HBasicBlock* join = graph()->CreateBasicBlock(); | 6378 HBasicBlock* join = graph()->CreateBasicBlock(); |
| 6373 | 6379 |
| 6374 for (int i = 0; i < untransitionable_maps.length(); ++i) { | 6380 for (int i = 0; i < untransitionable_maps.length(); ++i) { |
| 6375 Handle<Map> map = untransitionable_maps[i]; | 6381 Handle<Map> map = untransitionable_maps[i]; |
| 6376 if (!map->IsJSObjectMap()) continue; | 6382 if (!map->IsJSObjectMap()) continue; |
| 6377 ElementsKind elements_kind = map->elements_kind(); | 6383 ElementsKind elements_kind = map->elements_kind(); |
| 6378 HBasicBlock* this_map = graph()->CreateBasicBlock(); | 6384 HBasicBlock* this_map = graph()->CreateBasicBlock(); |
| 6379 HBasicBlock* other_map = graph()->CreateBasicBlock(); | 6385 HBasicBlock* other_map = graph()->CreateBasicBlock(); |
| 6380 HCompareMap* mapcompare = | 6386 HCompareMap* mapcompare = |
| 6381 New<HCompareMap>(object, map, this_map, other_map); | 6387 New<HCompareMap>(object, map, this_map, other_map); |
| 6382 FinishCurrentBlock(mapcompare); | 6388 FinishCurrentBlock(mapcompare); |
| 6383 | 6389 |
| 6384 set_current_block(this_map); | 6390 set_current_block(this_map); |
| 6385 HInstruction* access = NULL; | 6391 HInstruction* access = NULL; |
| 6386 if (IsDictionaryElementsKind(elements_kind)) { | 6392 if (IsDictionaryElementsKind(elements_kind)) { |
| 6387 access = access_type == STORE | 6393 access = AddInstruction(BuildKeyedGeneric(access_type, object, key, val)); |
| 6388 ? AddInstruction(BuildStoreKeyedGeneric(object, key, val)) | |
| 6389 : AddInstruction(BuildLoadKeyedGeneric(object, key)); | |
| 6390 } else { | 6394 } else { |
| 6391 ASSERT(IsFastElementsKind(elements_kind) || | 6395 ASSERT(IsFastElementsKind(elements_kind) || |
| 6392 IsExternalArrayElementsKind(elements_kind)); | 6396 IsExternalArrayElementsKind(elements_kind)); |
| 6393 LoadKeyedHoleMode load_mode = BuildKeyedHoleMode(map); | 6397 LoadKeyedHoleMode load_mode = BuildKeyedHoleMode(map); |
| 6394 // Happily, mapcompare is a checked object. | 6398 // Happily, mapcompare is a checked object. |
| 6395 access = BuildUncheckedMonomorphicElementAccess( | 6399 access = BuildUncheckedMonomorphicElementAccess( |
| 6396 mapcompare, key, val, | 6400 mapcompare, key, val, |
| 6397 map->instance_type() == JS_ARRAY_TYPE, | 6401 map->instance_type() == JS_ARRAY_TYPE, |
| 6398 elements_kind, access_type, | 6402 elements_kind, access_type, |
| 6399 load_mode, | 6403 load_mode, |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 6445 force_generic = true; | 6449 force_generic = true; |
| 6446 monomorphic = false; | 6450 monomorphic = false; |
| 6447 break; | 6451 break; |
| 6448 } | 6452 } |
| 6449 } | 6453 } |
| 6450 } | 6454 } |
| 6451 | 6455 |
| 6452 if (monomorphic) { | 6456 if (monomorphic) { |
| 6453 Handle<Map> map = types->first(); | 6457 Handle<Map> map = types->first(); |
| 6454 if (map->has_slow_elements_kind() || !map->IsJSObjectMap()) { | 6458 if (map->has_slow_elements_kind() || !map->IsJSObjectMap()) { |
| 6455 instr = access_type == STORE | 6459 instr = AddInstruction(BuildKeyedGeneric(access_type, obj, key, val)); |
| 6456 ? BuildStoreKeyedGeneric(obj, key, val) | |
| 6457 : BuildLoadKeyedGeneric(obj, key); | |
| 6458 AddInstruction(instr); | |
| 6459 } else { | 6460 } else { |
| 6460 BuildCheckHeapObject(obj); | 6461 BuildCheckHeapObject(obj); |
| 6461 instr = BuildMonomorphicElementAccess( | 6462 instr = BuildMonomorphicElementAccess( |
| 6462 obj, key, val, NULL, map, access_type, expr->GetStoreMode()); | 6463 obj, key, val, NULL, map, access_type, expr->GetStoreMode()); |
| 6463 } | 6464 } |
| 6464 } else if (!force_generic && (types != NULL && !types->is_empty())) { | 6465 } else if (!force_generic && (types != NULL && !types->is_empty())) { |
| 6465 return HandlePolymorphicElementAccess( | 6466 return HandlePolymorphicElementAccess( |
| 6466 obj, key, val, types, access_type, | 6467 obj, key, val, types, access_type, |
| 6467 expr->GetStoreMode(), has_side_effects); | 6468 expr->GetStoreMode(), has_side_effects); |
| 6468 } else { | 6469 } else { |
| 6469 if (access_type == STORE) { | 6470 if (access_type == STORE) { |
| 6470 if (expr->IsAssignment() && | 6471 if (expr->IsAssignment() && |
| 6471 expr->AsAssignment()->HasNoTypeInformation()) { | 6472 expr->AsAssignment()->HasNoTypeInformation()) { |
| 6472 Add<HDeoptimize>("Insufficient type feedback for keyed store", | 6473 Add<HDeoptimize>("Insufficient type feedback for keyed store", |
| 6473 Deoptimizer::SOFT); | 6474 Deoptimizer::SOFT); |
| 6474 } | 6475 } |
| 6475 instr = BuildStoreKeyedGeneric(obj, key, val); | |
| 6476 } else { | 6476 } else { |
| 6477 if (expr->AsProperty()->HasNoTypeInformation()) { | 6477 if (expr->AsProperty()->HasNoTypeInformation()) { |
| 6478 Add<HDeoptimize>("Insufficient type feedback for keyed load", | 6478 Add<HDeoptimize>("Insufficient type feedback for keyed load", |
| 6479 Deoptimizer::SOFT); | 6479 Deoptimizer::SOFT); |
| 6480 } | 6480 } |
| 6481 instr = BuildLoadKeyedGeneric(obj, key); | |
| 6482 } | 6481 } |
| 6483 AddInstruction(instr); | 6482 instr = AddInstruction(BuildKeyedGeneric(access_type, obj, key, val)); |
| 6484 } | 6483 } |
| 6485 *has_side_effects = instr->HasObservableSideEffects(); | 6484 *has_side_effects = instr->HasObservableSideEffects(); |
| 6486 return instr; | 6485 return instr; |
| 6487 } | 6486 } |
| 6488 | 6487 |
| 6489 | 6488 |
| 6490 HInstruction* HOptimizedGraphBuilder::BuildStoreKeyedGeneric( | |
| 6491 HValue* object, | |
| 6492 HValue* key, | |
| 6493 HValue* value) { | |
| 6494 return New<HStoreKeyedGeneric>( | |
| 6495 object, | |
| 6496 key, | |
| 6497 value, | |
| 6498 function_strict_mode_flag()); | |
| 6499 } | |
| 6500 | |
| 6501 | |
| 6502 void HOptimizedGraphBuilder::EnsureArgumentsArePushedForAccess() { | 6489 void HOptimizedGraphBuilder::EnsureArgumentsArePushedForAccess() { |
| 6503 // Outermost function already has arguments on the stack. | 6490 // Outermost function already has arguments on the stack. |
| 6504 if (function_state()->outer() == NULL) return; | 6491 if (function_state()->outer() == NULL) return; |
| 6505 | 6492 |
| 6506 if (function_state()->arguments_pushed()) return; | 6493 if (function_state()->arguments_pushed()) return; |
| 6507 | 6494 |
| 6508 // Push arguments when entering inlined function. | 6495 // Push arguments when entering inlined function. |
| 6509 HEnterInlined* entry = function_state()->entry(); | 6496 HEnterInlined* entry = function_state()->entry(); |
| 6510 entry->set_arguments_pushed(); | 6497 entry->set_arguments_pushed(); |
| 6511 | 6498 |
| (...skipping 4696 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 11208 if (ShouldProduceTraceOutput()) { | 11195 if (ShouldProduceTraceOutput()) { |
| 11209 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); | 11196 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); |
| 11210 } | 11197 } |
| 11211 | 11198 |
| 11212 #ifdef DEBUG | 11199 #ifdef DEBUG |
| 11213 graph_->Verify(false); // No full verify. | 11200 graph_->Verify(false); // No full verify. |
| 11214 #endif | 11201 #endif |
| 11215 } | 11202 } |
| 11216 | 11203 |
| 11217 } } // namespace v8::internal | 11204 } } // namespace v8::internal |
| OLD | NEW |