| OLD | NEW |
| 1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "src/hydrogen.h" | 5 #include "src/hydrogen.h" |
| 6 | 6 |
| 7 #include <sstream> | 7 #include <sstream> |
| 8 | 8 |
| 9 #include "src/v8.h" | 9 #include "src/v8.h" |
| 10 | 10 |
| (...skipping 321 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 332 | 332 |
| 333 | 333 |
| 334 void HBasicBlock::RegisterPredecessor(HBasicBlock* pred) { | 334 void HBasicBlock::RegisterPredecessor(HBasicBlock* pred) { |
| 335 if (HasPredecessor()) { | 335 if (HasPredecessor()) { |
| 336 // Only loop header blocks can have a predecessor added after | 336 // Only loop header blocks can have a predecessor added after |
| 337 // instructions have been added to the block (they have phis for all | 337 // instructions have been added to the block (they have phis for all |
| 338 // values in the environment, these phis may be eliminated later). | 338 // values in the environment, these phis may be eliminated later). |
| 339 DCHECK(IsLoopHeader() || first_ == NULL); | 339 DCHECK(IsLoopHeader() || first_ == NULL); |
| 340 HEnvironment* incoming_env = pred->last_environment(); | 340 HEnvironment* incoming_env = pred->last_environment(); |
| 341 if (IsLoopHeader()) { | 341 if (IsLoopHeader()) { |
| 342 DCHECK(phis()->length() == incoming_env->length()); | 342 DCHECK_EQ(phis()->length(), incoming_env->length()); |
| 343 for (int i = 0; i < phis_.length(); ++i) { | 343 for (int i = 0; i < phis_.length(); ++i) { |
| 344 phis_[i]->AddInput(incoming_env->values()->at(i)); | 344 phis_[i]->AddInput(incoming_env->values()->at(i)); |
| 345 } | 345 } |
| 346 } else { | 346 } else { |
| 347 last_environment()->AddIncomingEdge(this, pred->last_environment()); | 347 last_environment()->AddIncomingEdge(this, pred->last_environment()); |
| 348 } | 348 } |
| 349 } else if (!HasEnvironment() && !IsFinished()) { | 349 } else if (!HasEnvironment() && !IsFinished()) { |
| 350 DCHECK(!IsLoopHeader()); | 350 DCHECK(!IsLoopHeader()); |
| 351 SetInitialEnvironment(pred->last_environment()->Copy()); | 351 SetInitialEnvironment(pred->last_environment()->Copy()); |
| 352 } | 352 } |
| (...skipping 637 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 990 *else_continuation = else_record->block_; | 990 *else_continuation = else_record->block_; |
| 991 } | 991 } |
| 992 MergeAtJoinBlock* then_record = else_record->next_; | 992 MergeAtJoinBlock* then_record = else_record->next_; |
| 993 if (then_continuation != NULL) { | 993 if (then_continuation != NULL) { |
| 994 *then_continuation = then_record->block_; | 994 *then_continuation = then_record->block_; |
| 995 } | 995 } |
| 996 DCHECK(then_record->next_ == NULL); | 996 DCHECK(then_record->next_ == NULL); |
| 997 } | 997 } |
| 998 | 998 |
| 999 | 999 |
| 1000 void HGraphBuilder::IfBuilder::EndUnreachable() { |
| 1001 if (captured_) return; |
| 1002 Finish(); |
| 1003 builder()->set_current_block(nullptr); |
| 1004 } |
| 1005 |
| 1006 |
| 1000 void HGraphBuilder::IfBuilder::End() { | 1007 void HGraphBuilder::IfBuilder::End() { |
| 1001 if (captured_) return; | 1008 if (captured_) return; |
| 1002 Finish(); | 1009 Finish(); |
| 1003 | 1010 |
| 1004 int total_merged_blocks = normal_merge_at_join_block_count_ + | 1011 int total_merged_blocks = normal_merge_at_join_block_count_ + |
| 1005 deopt_merge_at_join_block_count_; | 1012 deopt_merge_at_join_block_count_; |
| 1006 DCHECK(total_merged_blocks >= 1); | 1013 DCHECK(total_merged_blocks >= 1); |
| 1007 HBasicBlock* merge_block = | 1014 HBasicBlock* merge_block = |
| 1008 total_merged_blocks == 1 ? NULL : builder()->graph()->CreateBasicBlock(); | 1015 total_merged_blocks == 1 ? NULL : builder()->graph()->CreateBasicBlock(); |
| 1009 | 1016 |
| (...skipping 2117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3127 // This smi value is reset to zero after every gc, overflow isn't a problem | 3134 // This smi value is reset to zero after every gc, overflow isn't a problem |
| 3128 // since the counter is bounded by the new space size. | 3135 // since the counter is bounded by the new space size. |
| 3129 memento_create_count->ClearFlag(HValue::kCanOverflow); | 3136 memento_create_count->ClearFlag(HValue::kCanOverflow); |
| 3130 Add<HStoreNamedField>( | 3137 Add<HStoreNamedField>( |
| 3131 allocation_site, HObjectAccess::ForAllocationSiteOffset( | 3138 allocation_site, HObjectAccess::ForAllocationSiteOffset( |
| 3132 AllocationSite::kPretenureCreateCountOffset), memento_create_count); | 3139 AllocationSite::kPretenureCreateCountOffset), memento_create_count); |
| 3133 } | 3140 } |
| 3134 } | 3141 } |
| 3135 | 3142 |
| 3136 | 3143 |
| 3144 HInstruction* HGraphBuilder::BuildGetNativeContext() { |
| 3145 // Get the global object, then the native context |
| 3146 HValue* global_object = Add<HLoadNamedField>( |
| 3147 context(), nullptr, |
| 3148 HObjectAccess::ForContextSlot(Context::GLOBAL_OBJECT_INDEX)); |
| 3149 return Add<HLoadNamedField>(global_object, nullptr, |
| 3150 HObjectAccess::ForObservableJSObjectOffset( |
| 3151 GlobalObject::kNativeContextOffset)); |
| 3152 } |
| 3153 |
| 3154 |
| 3137 HInstruction* HGraphBuilder::BuildGetNativeContext(HValue* closure) { | 3155 HInstruction* HGraphBuilder::BuildGetNativeContext(HValue* closure) { |
| 3138 // Get the global object, then the native context | 3156 // Get the global object, then the native context |
| 3139 HInstruction* context = Add<HLoadNamedField>( | 3157 HInstruction* context = Add<HLoadNamedField>( |
| 3140 closure, nullptr, HObjectAccess::ForFunctionContextPointer()); | 3158 closure, nullptr, HObjectAccess::ForFunctionContextPointer()); |
| 3141 HInstruction* global_object = Add<HLoadNamedField>( | 3159 HInstruction* global_object = Add<HLoadNamedField>( |
| 3142 context, nullptr, | 3160 context, nullptr, |
| 3143 HObjectAccess::ForContextSlot(Context::GLOBAL_OBJECT_INDEX)); | 3161 HObjectAccess::ForContextSlot(Context::GLOBAL_OBJECT_INDEX)); |
| 3144 HObjectAccess access = HObjectAccess::ForObservableJSObjectOffset( | 3162 HObjectAccess access = HObjectAccess::ForObservableJSObjectOffset( |
| 3145 GlobalObject::kNativeContextOffset); | 3163 GlobalObject::kNativeContextOffset); |
| 3146 return Add<HLoadNamedField>(global_object, nullptr, access); | 3164 return Add<HLoadNamedField>(global_object, nullptr, access); |
| 3147 } | 3165 } |
| 3148 | 3166 |
| 3149 | 3167 |
| 3150 HInstruction* HGraphBuilder::BuildGetScriptContext(int context_index) { | 3168 HInstruction* HGraphBuilder::BuildGetScriptContext(int context_index) { |
| 3151 HValue* native_context = BuildGetNativeContext(); | 3169 HValue* native_context = BuildGetNativeContext(); |
| 3152 HValue* script_context_table = Add<HLoadNamedField>( | 3170 HValue* script_context_table = Add<HLoadNamedField>( |
| 3153 native_context, nullptr, | 3171 native_context, nullptr, |
| 3154 HObjectAccess::ForContextSlot(Context::SCRIPT_CONTEXT_TABLE_INDEX)); | 3172 HObjectAccess::ForContextSlot(Context::SCRIPT_CONTEXT_TABLE_INDEX)); |
| 3155 return Add<HLoadNamedField>(script_context_table, nullptr, | 3173 return Add<HLoadNamedField>(script_context_table, nullptr, |
| 3156 HObjectAccess::ForScriptContext(context_index)); | 3174 HObjectAccess::ForScriptContext(context_index)); |
| 3157 } | 3175 } |
| 3158 | 3176 |
| 3159 | 3177 |
| 3160 HInstruction* HGraphBuilder::BuildGetNativeContext() { | 3178 HValue* HGraphBuilder::BuildGetParentContext(HValue* depth, int depth_value) { |
| 3161 // Get the global object, then the native context | 3179 HValue* script_context = context(); |
| 3162 HValue* global_object = Add<HLoadNamedField>( | 3180 if (depth != NULL) { |
| 3163 context(), nullptr, | 3181 HValue* zero = graph()->GetConstant0(); |
| 3164 HObjectAccess::ForContextSlot(Context::GLOBAL_OBJECT_INDEX)); | 3182 |
| 3165 return Add<HLoadNamedField>(global_object, nullptr, | 3183 Push(script_context); |
| 3166 HObjectAccess::ForObservableJSObjectOffset( | 3184 Push(depth); |
| 3167 GlobalObject::kNativeContextOffset)); | 3185 |
| 3186 LoopBuilder loop(this); |
| 3187 loop.BeginBody(2); // Drop script_context and depth from last environment |
| 3188 // to appease live range building without simulates. |
| 3189 depth = Pop(); |
| 3190 script_context = Pop(); |
| 3191 |
| 3192 script_context = Add<HLoadNamedField>( |
| 3193 script_context, nullptr, |
| 3194 HObjectAccess::ForContextSlot(Context::PREVIOUS_INDEX)); |
| 3195 depth = AddUncasted<HSub>(depth, graph()->GetConstant1()); |
| 3196 depth->ClearFlag(HValue::kCanOverflow); |
| 3197 |
| 3198 IfBuilder if_break(this); |
| 3199 if_break.If<HCompareNumericAndBranch, HValue*>(depth, zero, Token::EQ); |
| 3200 if_break.Then(); |
| 3201 { |
| 3202 Push(script_context); // The result. |
| 3203 loop.Break(); |
| 3204 } |
| 3205 if_break.Else(); |
| 3206 { |
| 3207 Push(script_context); |
| 3208 Push(depth); |
| 3209 } |
| 3210 loop.EndBody(); |
| 3211 if_break.End(); |
| 3212 |
| 3213 script_context = Pop(); |
| 3214 } else if (depth_value > 0) { |
| 3215 // Unroll the above loop. |
| 3216 for (int i = 0; i < depth_value; i++) { |
| 3217 script_context = Add<HLoadNamedField>( |
| 3218 script_context, nullptr, |
| 3219 HObjectAccess::ForContextSlot(Context::PREVIOUS_INDEX)); |
| 3220 } |
| 3221 } |
| 3222 return script_context; |
| 3168 } | 3223 } |
| 3169 | 3224 |
| 3170 | 3225 |
| 3171 HInstruction* HGraphBuilder::BuildGetArrayFunction() { | 3226 HInstruction* HGraphBuilder::BuildGetArrayFunction() { |
| 3172 HInstruction* native_context = BuildGetNativeContext(); | 3227 HInstruction* native_context = BuildGetNativeContext(); |
| 3173 HInstruction* index = | 3228 HInstruction* index = |
| 3174 Add<HConstant>(static_cast<int32_t>(Context::ARRAY_FUNCTION_INDEX)); | 3229 Add<HConstant>(static_cast<int32_t>(Context::ARRAY_FUNCTION_INDEX)); |
| 3175 return Add<HLoadKeyed>(native_context, index, nullptr, FAST_ELEMENTS); | 3230 return Add<HLoadKeyed>(native_context, index, nullptr, FAST_ELEMENTS); |
| 3176 } | 3231 } |
| 3177 | 3232 |
| (...skipping 10067 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 13245 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); | 13300 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); |
| 13246 } | 13301 } |
| 13247 | 13302 |
| 13248 #ifdef DEBUG | 13303 #ifdef DEBUG |
| 13249 graph_->Verify(false); // No full verify. | 13304 graph_->Verify(false); // No full verify. |
| 13250 #endif | 13305 #endif |
| 13251 } | 13306 } |
| 13252 | 13307 |
| 13253 } // namespace internal | 13308 } // namespace internal |
| 13254 } // namespace v8 | 13309 } // namespace v8 |
| OLD | NEW |