| 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 828 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 839 : first_false_block_; | 839 : first_false_block_; |
| 840 continuation->Capture(true_block, false_block); | 840 continuation->Capture(true_block, false_block); |
| 841 captured_ = true; | 841 captured_ = true; |
| 842 End(); | 842 End(); |
| 843 } | 843 } |
| 844 | 844 |
| 845 | 845 |
| 846 void HGraphBuilder::IfBuilder::JoinContinuation(HIfContinuation* continuation) { | 846 void HGraphBuilder::IfBuilder::JoinContinuation(HIfContinuation* continuation) { |
| 847 ASSERT(!finished_); | 847 ASSERT(!finished_); |
| 848 ASSERT(!captured_); | 848 ASSERT(!captured_); |
| 849 ASSERT(did_then_); |
| 850 if (!did_else_) Else(); |
| 849 HBasicBlock* true_block = last_true_block_ == NULL | 851 HBasicBlock* true_block = last_true_block_ == NULL |
| 850 ? first_true_block_ | 852 ? first_true_block_ |
| 851 : last_true_block_; | 853 : last_true_block_; |
| 852 HBasicBlock* false_block = did_else_ && (first_false_block_ != NULL) | 854 HBasicBlock* false_block = builder_->current_block(); |
| 853 ? builder_->current_block() | |
| 854 : first_false_block_; | |
| 855 if (true_block != NULL && !true_block->IsFinished()) { | 855 if (true_block != NULL && !true_block->IsFinished()) { |
| 856 ASSERT(continuation->IsTrueReachable()); | 856 ASSERT(continuation->IsTrueReachable()); |
| 857 builder_->GotoNoSimulate(true_block, continuation->true_branch()); | 857 builder_->GotoNoSimulate(true_block, continuation->true_branch()); |
| 858 } | 858 } |
| 859 if (false_block != NULL && !false_block->IsFinished()) { | 859 if (false_block != NULL && !false_block->IsFinished()) { |
| 860 ASSERT(continuation->IsFalseReachable()); | 860 ASSERT(continuation->IsFalseReachable()); |
| 861 builder_->GotoNoSimulate(false_block, continuation->false_branch()); | 861 builder_->GotoNoSimulate(false_block, continuation->false_branch()); |
| 862 } | 862 } |
| 863 captured_ = true; | 863 captured_ = true; |
| 864 End(); | 864 End(); |
| (...skipping 3628 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4493 Handle<FixedArray> constants = isolate()->factory()->empty_fixed_array(); | 4493 Handle<FixedArray> constants = isolate()->factory()->empty_fixed_array(); |
| 4494 int literal_index = expr->literal_index(); | 4494 int literal_index = expr->literal_index(); |
| 4495 | 4495 |
| 4496 Add<HPushArgument>(Add<HConstant>(literals)); | 4496 Add<HPushArgument>(Add<HConstant>(literals)); |
| 4497 Add<HPushArgument>(Add<HConstant>(literal_index)); | 4497 Add<HPushArgument>(Add<HConstant>(literal_index)); |
| 4498 Add<HPushArgument>(Add<HConstant>(constants)); | 4498 Add<HPushArgument>(Add<HConstant>(constants)); |
| 4499 | 4499 |
| 4500 // TODO(mvstanton): Consider a flag to turn off creation of any | 4500 // TODO(mvstanton): Consider a flag to turn off creation of any |
| 4501 // AllocationMementos for this call: we are in crankshaft and should have | 4501 // AllocationMementos for this call: we are in crankshaft and should have |
| 4502 // learned enough about transition behavior to stop emitting mementos. | 4502 // learned enough about transition behavior to stop emitting mementos. |
| 4503 Runtime::FunctionId function_id = (expr->depth() > 1) | 4503 Runtime::FunctionId function_id = Runtime::kCreateArrayLiteral; |
| 4504 ? Runtime::kCreateArrayLiteral : Runtime::kCreateArrayLiteralShallow; | |
| 4505 literal = Add<HCallRuntime>(isolate()->factory()->empty_string(), | 4504 literal = Add<HCallRuntime>(isolate()->factory()->empty_string(), |
| 4506 Runtime::FunctionForId(function_id), | 4505 Runtime::FunctionForId(function_id), |
| 4507 3); | 4506 3); |
| 4508 | 4507 |
| 4509 // De-opt if elements kind changed from boilerplate_elements_kind. | 4508 // De-opt if elements kind changed from boilerplate_elements_kind. |
| 4510 Handle<Map> map = Handle<Map>(boilerplate_object->map(), isolate()); | 4509 Handle<Map> map = Handle<Map>(boilerplate_object->map(), isolate()); |
| 4511 literal = Add<HCheckMaps>(literal, map, top_info()); | 4510 literal = Add<HCheckMaps>(literal, map, top_info()); |
| 4512 } | 4511 } |
| 4513 | 4512 |
| 4514 // The array is expected in the bailout environment during computation | 4513 // The array is expected in the bailout environment during computation |
| (...skipping 1057 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5572 HValue* dependency, | 5571 HValue* dependency, |
| 5573 Handle<Map> map, | 5572 Handle<Map> map, |
| 5574 bool is_store, | 5573 bool is_store, |
| 5575 KeyedAccessStoreMode store_mode) { | 5574 KeyedAccessStoreMode store_mode) { |
| 5576 HCheckMaps* checked_object = Add<HCheckMaps>(object, map, top_info(), | 5575 HCheckMaps* checked_object = Add<HCheckMaps>(object, map, top_info(), |
| 5577 dependency); | 5576 dependency); |
| 5578 if (dependency) { | 5577 if (dependency) { |
| 5579 checked_object->ClearGVNFlag(kDependsOnElementsKind); | 5578 checked_object->ClearGVNFlag(kDependsOnElementsKind); |
| 5580 } | 5579 } |
| 5581 | 5580 |
| 5581 if (is_store && map->prototype()->IsJSObject()) { |
| 5582 // monomorphic stores need a prototype chain check because shape |
| 5583 // changes could allow callbacks on elements in the chain that |
| 5584 // aren't compatible with monomorphic keyed stores. |
| 5585 Handle<JSObject> prototype(JSObject::cast(map->prototype())); |
| 5586 Object* holder = map->prototype(); |
| 5587 while (holder->GetPrototype(isolate())->IsJSObject()) { |
| 5588 holder = holder->GetPrototype(isolate()); |
| 5589 } |
| 5590 ASSERT(holder->GetPrototype(isolate())->IsNull()); |
| 5591 |
| 5592 BuildCheckPrototypeMaps(prototype, |
| 5593 Handle<JSObject>(JSObject::cast(holder))); |
| 5594 } |
| 5595 |
| 5582 LoadKeyedHoleMode load_mode = BuildKeyedHoleMode(map); | 5596 LoadKeyedHoleMode load_mode = BuildKeyedHoleMode(map); |
| 5583 return BuildUncheckedMonomorphicElementAccess( | 5597 return BuildUncheckedMonomorphicElementAccess( |
| 5584 checked_object, key, val, | 5598 checked_object, key, val, |
| 5585 map->instance_type() == JS_ARRAY_TYPE, | 5599 map->instance_type() == JS_ARRAY_TYPE, |
| 5586 map->elements_kind(), is_store, | 5600 map->elements_kind(), is_store, |
| 5587 load_mode, store_mode); | 5601 load_mode, store_mode); |
| 5588 } | 5602 } |
| 5589 | 5603 |
| 5590 | 5604 |
| 5591 HInstruction* HOptimizedGraphBuilder::TryBuildConsolidatedElementLoad( | 5605 HInstruction* HOptimizedGraphBuilder::TryBuildConsolidatedElementLoad( |
| (...skipping 193 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5785 HValue* val, | 5799 HValue* val, |
| 5786 Expression* expr, | 5800 Expression* expr, |
| 5787 bool is_store, | 5801 bool is_store, |
| 5788 bool* has_side_effects) { | 5802 bool* has_side_effects) { |
| 5789 ASSERT(!expr->IsPropertyName()); | 5803 ASSERT(!expr->IsPropertyName()); |
| 5790 HInstruction* instr = NULL; | 5804 HInstruction* instr = NULL; |
| 5791 | 5805 |
| 5792 SmallMapList* types; | 5806 SmallMapList* types; |
| 5793 bool monomorphic = ComputeReceiverTypes(expr, obj, &types); | 5807 bool monomorphic = ComputeReceiverTypes(expr, obj, &types); |
| 5794 | 5808 |
| 5809 bool force_generic = false; |
| 5810 if (is_store && (monomorphic || (types != NULL && !types->is_empty()))) { |
| 5811 // Stores can't be mono/polymorphic if their prototype chain has dictionary |
| 5812 // elements. However a receiver map that has dictionary elements itself |
| 5813 // should be left to normal mono/poly behavior (the other maps may benefit |
| 5814 // from highly optimized stores). |
| 5815 for (int i = 0; i < types->length(); i++) { |
| 5816 Handle<Map> current_map = types->at(i); |
| 5817 if (current_map->DictionaryElementsInPrototypeChainOnly()) { |
| 5818 force_generic = true; |
| 5819 monomorphic = false; |
| 5820 break; |
| 5821 } |
| 5822 } |
| 5823 } |
| 5824 |
| 5795 if (monomorphic) { | 5825 if (monomorphic) { |
| 5796 Handle<Map> map = types->first(); | 5826 Handle<Map> map = types->first(); |
| 5797 if (map->has_slow_elements_kind()) { | 5827 if (map->has_slow_elements_kind()) { |
| 5798 instr = is_store ? BuildStoreKeyedGeneric(obj, key, val) | 5828 instr = is_store ? BuildStoreKeyedGeneric(obj, key, val) |
| 5799 : BuildLoadKeyedGeneric(obj, key); | 5829 : BuildLoadKeyedGeneric(obj, key); |
| 5800 AddInstruction(instr); | 5830 AddInstruction(instr); |
| 5801 } else { | 5831 } else { |
| 5802 BuildCheckHeapObject(obj); | 5832 BuildCheckHeapObject(obj); |
| 5803 instr = BuildMonomorphicElementAccess( | 5833 instr = BuildMonomorphicElementAccess( |
| 5804 obj, key, val, NULL, map, is_store, expr->GetStoreMode()); | 5834 obj, key, val, NULL, map, is_store, expr->GetStoreMode()); |
| 5805 } | 5835 } |
| 5806 } else if (types != NULL && !types->is_empty()) { | 5836 } else if (!force_generic && (types != NULL && !types->is_empty())) { |
| 5807 return HandlePolymorphicElementAccess( | 5837 return HandlePolymorphicElementAccess( |
| 5808 obj, key, val, types, is_store, | 5838 obj, key, val, types, is_store, |
| 5809 expr->GetStoreMode(), has_side_effects); | 5839 expr->GetStoreMode(), has_side_effects); |
| 5810 } else { | 5840 } else { |
| 5811 if (is_store) { | 5841 if (is_store) { |
| 5812 if (expr->IsAssignment() && | 5842 if (expr->IsAssignment() && |
| 5813 expr->AsAssignment()->HasNoTypeInformation()) { | 5843 expr->AsAssignment()->HasNoTypeInformation()) { |
| 5814 Add<HDeoptimize>("Insufficient type feedback for keyed store", | 5844 Add<HDeoptimize>("Insufficient type feedback for keyed store", |
| 5815 Deoptimizer::SOFT); | 5845 Deoptimizer::SOFT); |
| 5816 } | 5846 } |
| (...skipping 4009 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9826 if (ShouldProduceTraceOutput()) { | 9856 if (ShouldProduceTraceOutput()) { |
| 9827 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); | 9857 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); |
| 9828 } | 9858 } |
| 9829 | 9859 |
| 9830 #ifdef DEBUG | 9860 #ifdef DEBUG |
| 9831 graph_->Verify(false); // No full verify. | 9861 graph_->Verify(false); // No full verify. |
| 9832 #endif | 9862 #endif |
| 9833 } | 9863 } |
| 9834 | 9864 |
| 9835 } } // namespace v8::internal | 9865 } } // namespace v8::internal |
| OLD | NEW |