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 |