| 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 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 141 ASSERT(last_environment() != NULL); | 141 ASSERT(last_environment() != NULL); |
| 142 ASSERT(!last_environment()->ast_id().IsNone()); | 142 ASSERT(!last_environment()->ast_id().IsNone()); |
| 143 HBlockEntry* entry = new(zone()) HBlockEntry(); | 143 HBlockEntry* entry = new(zone()) HBlockEntry(); |
| 144 entry->InitializeAsFirst(this); | 144 entry->InitializeAsFirst(this); |
| 145 first_ = last_ = entry; | 145 first_ = last_ = entry; |
| 146 } | 146 } |
| 147 instr->InsertAfter(last_); | 147 instr->InsertAfter(last_); |
| 148 } | 148 } |
| 149 | 149 |
| 150 | 150 |
| 151 HPhi* HBasicBlock::AddNewPhi(int merged_index) { |
| 152 if (graph()->IsInsideNoSideEffectsScope()) { |
| 153 merged_index = HPhi::kInvalidMergedIndex; |
| 154 } |
| 155 HPhi* phi = new(zone()) HPhi(merged_index, zone()); |
| 156 AddPhi(phi); |
| 157 return phi; |
| 158 } |
| 159 |
| 160 |
| 151 HSimulate* HBasicBlock::CreateSimulate(BailoutId ast_id, | 161 HSimulate* HBasicBlock::CreateSimulate(BailoutId ast_id, |
| 152 RemovableSimulate removable) { | 162 RemovableSimulate removable) { |
| 153 ASSERT(HasEnvironment()); | 163 ASSERT(HasEnvironment()); |
| 154 HEnvironment* environment = last_environment(); | 164 HEnvironment* environment = last_environment(); |
| 155 ASSERT(ast_id.IsNone() || | 165 ASSERT(ast_id.IsNone() || |
| 156 ast_id == BailoutId::StubEntry() || | 166 ast_id == BailoutId::StubEntry() || |
| 157 environment->closure()->shared()->VerifyBailoutId(ast_id)); | 167 environment->closure()->shared()->VerifyBailoutId(ast_id)); |
| 158 | 168 |
| 159 int push_count = environment->push_count(); | 169 int push_count = environment->push_count(); |
| 160 int pop_count = environment->pop_count(); | 170 int pop_count = environment->pop_count(); |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 196 FunctionState* state, | 206 FunctionState* state, |
| 197 bool add_simulate) { | 207 bool add_simulate) { |
| 198 bool drop_extra = state != NULL && | 208 bool drop_extra = state != NULL && |
| 199 state->inlining_kind() == DROP_EXTRA_ON_RETURN; | 209 state->inlining_kind() == DROP_EXTRA_ON_RETURN; |
| 200 | 210 |
| 201 if (block->IsInlineReturnTarget()) { | 211 if (block->IsInlineReturnTarget()) { |
| 202 AddInstruction(new(zone()) HLeaveInlined()); | 212 AddInstruction(new(zone()) HLeaveInlined()); |
| 203 UpdateEnvironment(last_environment()->DiscardInlined(drop_extra)); | 213 UpdateEnvironment(last_environment()->DiscardInlined(drop_extra)); |
| 204 } | 214 } |
| 205 | 215 |
| 206 if (add_simulate) AddSimulate(BailoutId::None()); | 216 if (add_simulate) AddNewSimulate(BailoutId::None()); |
| 207 HGoto* instr = new(zone()) HGoto(block); | 217 HGoto* instr = new(zone()) HGoto(block); |
| 208 Finish(instr); | 218 Finish(instr); |
| 209 } | 219 } |
| 210 | 220 |
| 211 | 221 |
| 212 void HBasicBlock::AddLeaveInlined(HValue* return_value, | 222 void HBasicBlock::AddLeaveInlined(HValue* return_value, |
| 213 FunctionState* state) { | 223 FunctionState* state) { |
| 214 HBasicBlock* target = state->function_return(); | 224 HBasicBlock* target = state->function_return(); |
| 215 bool drop_extra = state->inlining_kind() == DROP_EXTRA_ON_RETURN; | 225 bool drop_extra = state->inlining_kind() == DROP_EXTRA_ON_RETURN; |
| 216 | 226 |
| 217 ASSERT(target->IsInlineReturnTarget()); | 227 ASSERT(target->IsInlineReturnTarget()); |
| 218 ASSERT(return_value != NULL); | 228 ASSERT(return_value != NULL); |
| 219 AddInstruction(new(zone()) HLeaveInlined()); | 229 AddInstruction(new(zone()) HLeaveInlined()); |
| 220 UpdateEnvironment(last_environment()->DiscardInlined(drop_extra)); | 230 UpdateEnvironment(last_environment()->DiscardInlined(drop_extra)); |
| 221 last_environment()->Push(return_value); | 231 last_environment()->Push(return_value); |
| 222 AddSimulate(BailoutId::None()); | 232 AddNewSimulate(BailoutId::None()); |
| 223 HGoto* instr = new(zone()) HGoto(target); | 233 HGoto* instr = new(zone()) HGoto(target); |
| 224 Finish(instr); | 234 Finish(instr); |
| 225 } | 235 } |
| 226 | 236 |
| 227 | 237 |
| 228 void HBasicBlock::SetInitialEnvironment(HEnvironment* env) { | 238 void HBasicBlock::SetInitialEnvironment(HEnvironment* env) { |
| 229 ASSERT(!HasEnvironment()); | 239 ASSERT(!HasEnvironment()); |
| 230 ASSERT(first() == NULL); | 240 ASSERT(first() == NULL); |
| 231 UpdateEnvironment(env); | 241 UpdateEnvironment(env); |
| 232 } | 242 } |
| (...skipping 664 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 897 body_block_ = NULL; | 907 body_block_ = NULL; |
| 898 exit_block_ = NULL; | 908 exit_block_ = NULL; |
| 899 } | 909 } |
| 900 | 910 |
| 901 | 911 |
| 902 HValue* HGraphBuilder::LoopBuilder::BeginBody( | 912 HValue* HGraphBuilder::LoopBuilder::BeginBody( |
| 903 HValue* initial, | 913 HValue* initial, |
| 904 HValue* terminating, | 914 HValue* terminating, |
| 905 Token::Value token) { | 915 Token::Value token) { |
| 906 HEnvironment* env = builder_->environment(); | 916 HEnvironment* env = builder_->environment(); |
| 907 phi_ = new(zone()) HPhi(env->values()->length(), zone()); | 917 phi_ = header_block_->AddNewPhi(env->values()->length()); |
| 908 header_block_->AddPhi(phi_); | |
| 909 phi_->AddInput(initial); | 918 phi_->AddInput(initial); |
| 910 env->Push(initial); | 919 env->Push(initial); |
| 911 builder_->current_block()->GotoNoSimulate(header_block_); | 920 builder_->current_block()->GotoNoSimulate(header_block_); |
| 912 | 921 |
| 913 HEnvironment* body_env = env->Copy(); | 922 HEnvironment* body_env = env->Copy(); |
| 914 HEnvironment* exit_env = env->Copy(); | 923 HEnvironment* exit_env = env->Copy(); |
| 915 body_block_ = builder_->CreateBasicBlock(body_env); | 924 body_block_ = builder_->CreateBasicBlock(body_env); |
| 916 exit_block_ = builder_->CreateBasicBlock(exit_env); | 925 exit_block_ = builder_->CreateBasicBlock(exit_env); |
| 917 // Remove the phi from the expression stack | 926 // Remove the phi from the expression stack |
| 918 body_env->Pop(); | 927 body_env->Pop(); |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 975 set_current_block(graph()->entry_block()); | 984 set_current_block(graph()->entry_block()); |
| 976 if (!BuildGraph()) return NULL; | 985 if (!BuildGraph()) return NULL; |
| 977 graph()->FinalizeUniqueValueIds(); | 986 graph()->FinalizeUniqueValueIds(); |
| 978 return graph_; | 987 return graph_; |
| 979 } | 988 } |
| 980 | 989 |
| 981 | 990 |
| 982 HInstruction* HGraphBuilder::AddInstruction(HInstruction* instr) { | 991 HInstruction* HGraphBuilder::AddInstruction(HInstruction* instr) { |
| 983 ASSERT(current_block() != NULL); | 992 ASSERT(current_block() != NULL); |
| 984 current_block()->AddInstruction(instr); | 993 current_block()->AddInstruction(instr); |
| 985 if (no_side_effects_scope_count_ > 0) { | 994 if (graph()->IsInsideNoSideEffectsScope()) { |
| 986 instr->SetFlag(HValue::kHasNoObservableSideEffects); | 995 instr->SetFlag(HValue::kHasNoObservableSideEffects); |
| 987 } | 996 } |
| 988 return instr; | 997 return instr; |
| 989 } | 998 } |
| 990 | 999 |
| 991 | 1000 |
| 992 void HGraphBuilder::AddIncrementCounter(StatsCounter* counter, | 1001 void HGraphBuilder::AddIncrementCounter(StatsCounter* counter, |
| 993 HValue* context) { | 1002 HValue* context) { |
| 994 if (FLAG_native_code_counters && counter->Enabled()) { | 1003 if (FLAG_native_code_counters && counter->Enabled()) { |
| 995 HValue* reference = Add<HConstant>(ExternalReference(counter)); | 1004 HValue* reference = Add<HConstant>(ExternalReference(counter)); |
| 996 HValue* old_value = Add<HLoadNamedField>(reference, | 1005 HValue* old_value = Add<HLoadNamedField>(reference, |
| 997 HObjectAccess::ForCounter()); | 1006 HObjectAccess::ForCounter()); |
| 998 HValue* new_value = Add<HAdd>(old_value, graph()->GetConstant1()); | 1007 HValue* new_value = Add<HAdd>(old_value, graph()->GetConstant1()); |
| 999 new_value->ClearFlag(HValue::kCanOverflow); // Ignore counter overflow | 1008 new_value->ClearFlag(HValue::kCanOverflow); // Ignore counter overflow |
| 1000 Add<HStoreNamedField>(reference, HObjectAccess::ForCounter(), | 1009 Add<HStoreNamedField>(reference, HObjectAccess::ForCounter(), |
| 1001 new_value); | 1010 new_value); |
| 1002 } | 1011 } |
| 1003 } | 1012 } |
| 1004 | 1013 |
| 1005 | 1014 |
| 1006 void HGraphBuilder::AddSimulate(BailoutId id, | 1015 void HGraphBuilder::AddSimulate(BailoutId id, |
| 1007 RemovableSimulate removable) { | 1016 RemovableSimulate removable) { |
| 1008 ASSERT(current_block() != NULL); | 1017 ASSERT(current_block() != NULL); |
| 1009 ASSERT(no_side_effects_scope_count_ == 0); | 1018 ASSERT(!graph()->IsInsideNoSideEffectsScope()); |
| 1010 current_block()->AddSimulate(id, removable); | 1019 current_block()->AddNewSimulate(id, removable); |
| 1011 } | 1020 } |
| 1012 | 1021 |
| 1013 | 1022 |
| 1014 HBasicBlock* HGraphBuilder::CreateBasicBlock(HEnvironment* env) { | 1023 HBasicBlock* HGraphBuilder::CreateBasicBlock(HEnvironment* env) { |
| 1015 HBasicBlock* b = graph()->CreateBasicBlock(); | 1024 HBasicBlock* b = graph()->CreateBasicBlock(); |
| 1016 b->SetInitialEnvironment(env); | 1025 b->SetInitialEnvironment(env); |
| 1017 return b; | 1026 return b; |
| 1018 } | 1027 } |
| 1019 | 1028 |
| 1020 | 1029 |
| 1021 HBasicBlock* HGraphBuilder::CreateLoopHeaderBlock() { | 1030 HBasicBlock* HGraphBuilder::CreateLoopHeaderBlock() { |
| 1022 HBasicBlock* header = graph()->CreateBasicBlock(); | 1031 HBasicBlock* header = graph()->CreateBasicBlock(); |
| 1023 HEnvironment* entry_env = environment()->CopyAsLoopHeader(header); | 1032 HEnvironment* entry_env = environment()->CopyAsLoopHeader(header); |
| 1024 header->SetInitialEnvironment(entry_env); | 1033 header->SetInitialEnvironment(entry_env); |
| 1025 header->AttachLoopInformation(); | 1034 header->AttachLoopInformation(); |
| 1026 return header; | 1035 return header; |
| 1027 } | 1036 } |
| 1028 | 1037 |
| 1029 | 1038 |
| 1030 HValue* HGraphBuilder::BuildCheckHeapObject(HValue* obj) { | 1039 HValue* HGraphBuilder::BuildCheckHeapObject(HValue* obj) { |
| 1031 if (obj->type().IsHeapObject()) return obj; | 1040 if (obj->type().IsHeapObject()) return obj; |
| 1032 return Add<HCheckHeapObject>(obj); | 1041 return Add<HCheckHeapObject>(obj); |
| 1033 } | 1042 } |
| 1034 | 1043 |
| 1035 | 1044 |
| 1036 void HGraphBuilder::FinishExitWithHardDeoptimization( | 1045 void HGraphBuilder::FinishExitWithHardDeoptimization( |
| 1037 HBasicBlock* continuation) { | 1046 HBasicBlock* continuation) { |
| 1038 PadEnvironmentForContinuation(current_block(), continuation); | 1047 PadEnvironmentForContinuation(current_block(), continuation); |
| 1039 Add<HDeoptimize>(Deoptimizer::EAGER); | 1048 Add<HDeoptimize>(Deoptimizer::EAGER); |
| 1040 if (no_side_effects_scope_count_ > 0) { | 1049 if (graph()->IsInsideNoSideEffectsScope()) { |
| 1041 current_block()->GotoNoSimulate(continuation); | 1050 current_block()->GotoNoSimulate(continuation); |
| 1042 } else { | 1051 } else { |
| 1043 current_block()->Goto(continuation); | 1052 current_block()->Goto(continuation); |
| 1044 } | 1053 } |
| 1045 } | 1054 } |
| 1046 | 1055 |
| 1047 | 1056 |
| 1048 void HGraphBuilder::PadEnvironmentForContinuation( | 1057 void HGraphBuilder::PadEnvironmentForContinuation( |
| 1049 HBasicBlock* from, | 1058 HBasicBlock* from, |
| 1050 HBasicBlock* continuation) { | 1059 HBasicBlock* continuation) { |
| (...skipping 991 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2042 phi_list_(NULL), | 2051 phi_list_(NULL), |
| 2043 uint32_instructions_(NULL), | 2052 uint32_instructions_(NULL), |
| 2044 osr_(NULL), | 2053 osr_(NULL), |
| 2045 info_(info), | 2054 info_(info), |
| 2046 zone_(info->zone()), | 2055 zone_(info->zone()), |
| 2047 is_recursive_(false), | 2056 is_recursive_(false), |
| 2048 use_optimistic_licm_(false), | 2057 use_optimistic_licm_(false), |
| 2049 has_soft_deoptimize_(false), | 2058 has_soft_deoptimize_(false), |
| 2050 depends_on_empty_array_proto_elements_(false), | 2059 depends_on_empty_array_proto_elements_(false), |
| 2051 type_change_checksum_(0), | 2060 type_change_checksum_(0), |
| 2052 maximum_environment_size_(0) { | 2061 maximum_environment_size_(0), |
| 2062 no_side_effects_scope_count_(0) { |
| 2053 if (info->IsStub()) { | 2063 if (info->IsStub()) { |
| 2054 HydrogenCodeStub* stub = info->code_stub(); | 2064 HydrogenCodeStub* stub = info->code_stub(); |
| 2055 CodeStubInterfaceDescriptor* descriptor = | 2065 CodeStubInterfaceDescriptor* descriptor = |
| 2056 stub->GetInterfaceDescriptor(isolate_); | 2066 stub->GetInterfaceDescriptor(isolate_); |
| 2057 start_environment_ = | 2067 start_environment_ = |
| 2058 new(zone_) HEnvironment(zone_, descriptor->environment_length()); | 2068 new(zone_) HEnvironment(zone_, descriptor->environment_length()); |
| 2059 } else { | 2069 } else { |
| 2060 start_environment_ = | 2070 start_environment_ = |
| 2061 new(zone_) HEnvironment(NULL, info->scope(), info->closure(), zone_); | 2071 new(zone_) HEnvironment(NULL, info->scope(), info->closure(), zone_); |
| 2062 } | 2072 } |
| (...skipping 7145 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9208 ASSERT(!block->IsLoopHeader()); | 9218 ASSERT(!block->IsLoopHeader()); |
| 9209 ASSERT(values_.length() == other->values_.length()); | 9219 ASSERT(values_.length() == other->values_.length()); |
| 9210 | 9220 |
| 9211 int length = values_.length(); | 9221 int length = values_.length(); |
| 9212 for (int i = 0; i < length; ++i) { | 9222 for (int i = 0; i < length; ++i) { |
| 9213 HValue* value = values_[i]; | 9223 HValue* value = values_[i]; |
| 9214 if (value != NULL && value->IsPhi() && value->block() == block) { | 9224 if (value != NULL && value->IsPhi() && value->block() == block) { |
| 9215 // There is already a phi for the i'th value. | 9225 // There is already a phi for the i'th value. |
| 9216 HPhi* phi = HPhi::cast(value); | 9226 HPhi* phi = HPhi::cast(value); |
| 9217 // Assert index is correct and that we haven't missed an incoming edge. | 9227 // Assert index is correct and that we haven't missed an incoming edge. |
| 9218 ASSERT(phi->merged_index() == i); | 9228 ASSERT(phi->merged_index() == i || !phi->HasMergedIndex()); |
| 9219 ASSERT(phi->OperandCount() == block->predecessors()->length()); | 9229 ASSERT(phi->OperandCount() == block->predecessors()->length()); |
| 9220 phi->AddInput(other->values_[i]); | 9230 phi->AddInput(other->values_[i]); |
| 9221 } else if (values_[i] != other->values_[i]) { | 9231 } else if (values_[i] != other->values_[i]) { |
| 9222 // There is a fresh value on the incoming edge, a phi is needed. | 9232 // There is a fresh value on the incoming edge, a phi is needed. |
| 9223 ASSERT(values_[i] != NULL && other->values_[i] != NULL); | 9233 ASSERT(values_[i] != NULL && other->values_[i] != NULL); |
| 9224 HPhi* phi = new(zone()) HPhi(i, zone()); | 9234 HPhi* phi = block->AddNewPhi(i); |
| 9225 HValue* old_value = values_[i]; | 9235 HValue* old_value = values_[i]; |
| 9226 for (int j = 0; j < block->predecessors()->length(); j++) { | 9236 for (int j = 0; j < block->predecessors()->length(); j++) { |
| 9227 phi->AddInput(old_value); | 9237 phi->AddInput(old_value); |
| 9228 } | 9238 } |
| 9229 phi->AddInput(other->values_[i]); | 9239 phi->AddInput(other->values_[i]); |
| 9230 this->values_[i] = phi; | 9240 this->values_[i] = phi; |
| 9231 block->AddPhi(phi); | |
| 9232 } | 9241 } |
| 9233 } | 9242 } |
| 9234 } | 9243 } |
| 9235 | 9244 |
| 9236 | 9245 |
| 9237 void HEnvironment::Bind(int index, HValue* value) { | 9246 void HEnvironment::Bind(int index, HValue* value) { |
| 9238 ASSERT(value != NULL); | 9247 ASSERT(value != NULL); |
| 9239 assigned_variables_.Add(index, zone()); | 9248 assigned_variables_.Add(index, zone()); |
| 9240 values_[index] = value; | 9249 values_[index] = value; |
| 9241 } | 9250 } |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9282 HEnvironment* HEnvironment::CopyWithoutHistory() const { | 9291 HEnvironment* HEnvironment::CopyWithoutHistory() const { |
| 9283 HEnvironment* result = Copy(); | 9292 HEnvironment* result = Copy(); |
| 9284 result->ClearHistory(); | 9293 result->ClearHistory(); |
| 9285 return result; | 9294 return result; |
| 9286 } | 9295 } |
| 9287 | 9296 |
| 9288 | 9297 |
| 9289 HEnvironment* HEnvironment::CopyAsLoopHeader(HBasicBlock* loop_header) const { | 9298 HEnvironment* HEnvironment::CopyAsLoopHeader(HBasicBlock* loop_header) const { |
| 9290 HEnvironment* new_env = Copy(); | 9299 HEnvironment* new_env = Copy(); |
| 9291 for (int i = 0; i < values_.length(); ++i) { | 9300 for (int i = 0; i < values_.length(); ++i) { |
| 9292 HPhi* phi = new(zone()) HPhi(i, zone()); | 9301 HPhi* phi = loop_header->AddNewPhi(i); |
| 9293 phi->AddInput(values_[i]); | 9302 phi->AddInput(values_[i]); |
| 9294 new_env->values_[i] = phi; | 9303 new_env->values_[i] = phi; |
| 9295 loop_header->AddPhi(phi); | |
| 9296 } | 9304 } |
| 9297 new_env->ClearHistory(); | 9305 new_env->ClearHistory(); |
| 9298 return new_env; | 9306 return new_env; |
| 9299 } | 9307 } |
| 9300 | 9308 |
| 9301 | 9309 |
| 9302 HEnvironment* HEnvironment::CreateStubEnvironment(HEnvironment* outer, | 9310 HEnvironment* HEnvironment::CreateStubEnvironment(HEnvironment* outer, |
| 9303 Handle<JSFunction> target, | 9311 Handle<JSFunction> target, |
| 9304 FrameType frame_type, | 9312 FrameType frame_type, |
| 9305 int arguments) const { | 9313 int arguments) const { |
| (...skipping 401 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9707 if (ShouldProduceTraceOutput()) { | 9715 if (ShouldProduceTraceOutput()) { |
| 9708 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); | 9716 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); |
| 9709 } | 9717 } |
| 9710 | 9718 |
| 9711 #ifdef DEBUG | 9719 #ifdef DEBUG |
| 9712 graph_->Verify(false); // No full verify. | 9720 graph_->Verify(false); // No full verify. |
| 9713 #endif | 9721 #endif |
| 9714 } | 9722 } |
| 9715 | 9723 |
| 9716 } } // namespace v8::internal | 9724 } } // namespace v8::internal |
| OLD | NEW |