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 |