OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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 2502 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2513 return NULL; | 2513 return NULL; |
2514 } | 2514 } |
2515 graph()->EliminateRedundantPhis(); | 2515 graph()->EliminateRedundantPhis(); |
2516 if (!graph()->CheckArgumentsPhiUses()) { | 2516 if (!graph()->CheckArgumentsPhiUses()) { |
2517 Bailout("Unsupported phi use of arguments"); | 2517 Bailout("Unsupported phi use of arguments"); |
2518 return NULL; | 2518 return NULL; |
2519 } | 2519 } |
2520 if (FLAG_eliminate_dead_phis) graph()->EliminateUnreachablePhis(); | 2520 if (FLAG_eliminate_dead_phis) graph()->EliminateUnreachablePhis(); |
2521 graph()->CollectPhis(); | 2521 graph()->CollectPhis(); |
2522 | 2522 |
| 2523 if (graph()->has_osr_loop_entry()) { |
| 2524 const ZoneList<HPhi*>* phis = graph()->osr_loop_entry()->phis(); |
| 2525 for (int j = 0; j < phis->length(); j++) { |
| 2526 HPhi* phi = phis->at(j); |
| 2527 graph()->osr_values()->at(phi->merged_index())->set_incoming_value(phi); |
| 2528 } |
| 2529 } |
| 2530 |
2523 HInferRepresentation rep(graph()); | 2531 HInferRepresentation rep(graph()); |
2524 rep.Analyze(); | 2532 rep.Analyze(); |
2525 | 2533 |
2526 graph()->MarkDeoptimizeOnUndefined(); | 2534 graph()->MarkDeoptimizeOnUndefined(); |
2527 graph()->InsertRepresentationChanges(); | 2535 graph()->InsertRepresentationChanges(); |
2528 | 2536 |
2529 graph()->InitializeInferredTypes(); | 2537 graph()->InitializeInferredTypes(); |
2530 graph()->Canonicalize(); | 2538 graph()->Canonicalize(); |
2531 | 2539 |
2532 // Perform common subexpression elimination and loop-invariant code motion. | 2540 // Perform common subexpression elimination and loop-invariant code motion. |
(...skipping 552 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3085 set_current_block(break_block); | 3093 set_current_block(break_block); |
3086 } | 3094 } |
3087 } | 3095 } |
3088 | 3096 |
3089 | 3097 |
3090 bool HGraphBuilder::HasOsrEntryAt(IterationStatement* statement) { | 3098 bool HGraphBuilder::HasOsrEntryAt(IterationStatement* statement) { |
3091 return statement->OsrEntryId() == info()->osr_ast_id(); | 3099 return statement->OsrEntryId() == info()->osr_ast_id(); |
3092 } | 3100 } |
3093 | 3101 |
3094 | 3102 |
3095 void HGraphBuilder::PreProcessOsrEntry(IterationStatement* statement) { | 3103 bool HGraphBuilder::PreProcessOsrEntry(IterationStatement* statement) { |
3096 if (!HasOsrEntryAt(statement)) return; | 3104 if (!HasOsrEntryAt(statement)) return false; |
3097 | 3105 |
3098 HBasicBlock* non_osr_entry = graph()->CreateBasicBlock(); | 3106 HBasicBlock* non_osr_entry = graph()->CreateBasicBlock(); |
3099 HBasicBlock* osr_entry = graph()->CreateBasicBlock(); | 3107 HBasicBlock* osr_entry = graph()->CreateBasicBlock(); |
3100 HValue* true_value = graph()->GetConstantTrue(); | 3108 HValue* true_value = graph()->GetConstantTrue(); |
3101 HBranch* test = new(zone()) HBranch(true_value, non_osr_entry, osr_entry); | 3109 HBranch* test = new(zone()) HBranch(true_value, non_osr_entry, osr_entry); |
3102 current_block()->Finish(test); | 3110 current_block()->Finish(test); |
3103 | 3111 |
3104 HBasicBlock* loop_predecessor = graph()->CreateBasicBlock(); | 3112 HBasicBlock* loop_predecessor = graph()->CreateBasicBlock(); |
3105 non_osr_entry->Goto(loop_predecessor); | 3113 non_osr_entry->Goto(loop_predecessor); |
3106 | 3114 |
3107 set_current_block(osr_entry); | 3115 set_current_block(osr_entry); |
3108 int osr_entry_id = statement->OsrEntryId(); | 3116 int osr_entry_id = statement->OsrEntryId(); |
3109 int first_expression_index = environment()->first_expression_index(); | 3117 int first_expression_index = environment()->first_expression_index(); |
3110 int length = environment()->length(); | 3118 int length = environment()->length(); |
| 3119 ZoneList<HUnknownOSRValue*>* osr_values = |
| 3120 new(zone()) ZoneList<HUnknownOSRValue*>(length); |
| 3121 |
3111 for (int i = 0; i < first_expression_index; ++i) { | 3122 for (int i = 0; i < first_expression_index; ++i) { |
3112 HUnknownOSRValue* osr_value = new(zone()) HUnknownOSRValue; | 3123 HUnknownOSRValue* osr_value = new(zone()) HUnknownOSRValue; |
3113 AddInstruction(osr_value); | 3124 AddInstruction(osr_value); |
3114 environment()->Bind(i, osr_value); | 3125 environment()->Bind(i, osr_value); |
| 3126 osr_values->Add(osr_value); |
3115 } | 3127 } |
3116 | 3128 |
3117 if (first_expression_index != length) { | 3129 if (first_expression_index != length) { |
3118 environment()->Drop(length - first_expression_index); | 3130 environment()->Drop(length - first_expression_index); |
3119 for (int i = first_expression_index; i < length; ++i) { | 3131 for (int i = first_expression_index; i < length; ++i) { |
3120 HUnknownOSRValue* osr_value = new(zone()) HUnknownOSRValue; | 3132 HUnknownOSRValue* osr_value = new(zone()) HUnknownOSRValue; |
3121 AddInstruction(osr_value); | 3133 AddInstruction(osr_value); |
3122 environment()->Push(osr_value); | 3134 environment()->Push(osr_value); |
| 3135 osr_values->Add(osr_value); |
3123 } | 3136 } |
3124 } | 3137 } |
3125 | 3138 |
| 3139 graph()->set_osr_values(osr_values); |
| 3140 |
3126 AddSimulate(osr_entry_id); | 3141 AddSimulate(osr_entry_id); |
3127 AddInstruction(new(zone()) HOsrEntry(osr_entry_id)); | 3142 AddInstruction(new(zone()) HOsrEntry(osr_entry_id)); |
3128 HContext* context = new(zone()) HContext; | 3143 HContext* context = new(zone()) HContext; |
3129 AddInstruction(context); | 3144 AddInstruction(context); |
3130 environment()->BindContext(context); | 3145 environment()->BindContext(context); |
3131 current_block()->Goto(loop_predecessor); | 3146 current_block()->Goto(loop_predecessor); |
3132 loop_predecessor->SetJoinId(statement->EntryId()); | 3147 loop_predecessor->SetJoinId(statement->EntryId()); |
3133 set_current_block(loop_predecessor); | 3148 set_current_block(loop_predecessor); |
| 3149 return true; |
3134 } | 3150 } |
3135 | 3151 |
3136 | 3152 |
3137 void HGraphBuilder::VisitLoopBody(IterationStatement* stmt, | 3153 void HGraphBuilder::VisitLoopBody(IterationStatement* stmt, |
3138 HBasicBlock* loop_entry, | 3154 HBasicBlock* loop_entry, |
3139 BreakAndContinueInfo* break_info) { | 3155 BreakAndContinueInfo* break_info) { |
3140 BreakAndContinueScope push(break_info, this); | 3156 BreakAndContinueScope push(break_info, this); |
3141 AddSimulate(stmt->StackCheckId()); | 3157 AddSimulate(stmt->StackCheckId()); |
3142 HValue* context = environment()->LookupContext(); | 3158 HValue* context = environment()->LookupContext(); |
3143 HStackCheck* stack_check = | 3159 HStackCheck* stack_check = |
3144 new(zone()) HStackCheck(context, HStackCheck::kBackwardsBranch); | 3160 new(zone()) HStackCheck(context, HStackCheck::kBackwardsBranch); |
3145 AddInstruction(stack_check); | 3161 AddInstruction(stack_check); |
3146 ASSERT(loop_entry->IsLoopHeader()); | 3162 ASSERT(loop_entry->IsLoopHeader()); |
3147 loop_entry->loop_information()->set_stack_check(stack_check); | 3163 loop_entry->loop_information()->set_stack_check(stack_check); |
3148 CHECK_BAILOUT(Visit(stmt->body())); | 3164 CHECK_BAILOUT(Visit(stmt->body())); |
3149 } | 3165 } |
3150 | 3166 |
3151 | 3167 |
3152 void HGraphBuilder::VisitDoWhileStatement(DoWhileStatement* stmt) { | 3168 void HGraphBuilder::VisitDoWhileStatement(DoWhileStatement* stmt) { |
3153 ASSERT(!HasStackOverflow()); | 3169 ASSERT(!HasStackOverflow()); |
3154 ASSERT(current_block() != NULL); | 3170 ASSERT(current_block() != NULL); |
3155 ASSERT(current_block()->HasPredecessor()); | 3171 ASSERT(current_block()->HasPredecessor()); |
3156 ASSERT(current_block() != NULL); | 3172 ASSERT(current_block() != NULL); |
3157 PreProcessOsrEntry(stmt); | 3173 bool osr_entry = PreProcessOsrEntry(stmt); |
3158 HBasicBlock* loop_entry = CreateLoopHeaderBlock(); | 3174 HBasicBlock* loop_entry = CreateLoopHeaderBlock(); |
3159 current_block()->Goto(loop_entry); | 3175 current_block()->Goto(loop_entry); |
3160 set_current_block(loop_entry); | 3176 set_current_block(loop_entry); |
| 3177 if (osr_entry) graph()->set_osr_loop_entry(loop_entry); |
3161 | 3178 |
3162 BreakAndContinueInfo break_info(stmt); | 3179 BreakAndContinueInfo break_info(stmt); |
3163 CHECK_BAILOUT(VisitLoopBody(stmt, loop_entry, &break_info)); | 3180 CHECK_BAILOUT(VisitLoopBody(stmt, loop_entry, &break_info)); |
3164 HBasicBlock* body_exit = | 3181 HBasicBlock* body_exit = |
3165 JoinContinue(stmt, current_block(), break_info.continue_block()); | 3182 JoinContinue(stmt, current_block(), break_info.continue_block()); |
3166 HBasicBlock* loop_successor = NULL; | 3183 HBasicBlock* loop_successor = NULL; |
3167 if (body_exit != NULL && !stmt->cond()->ToBooleanIsTrue()) { | 3184 if (body_exit != NULL && !stmt->cond()->ToBooleanIsTrue()) { |
3168 set_current_block(body_exit); | 3185 set_current_block(body_exit); |
3169 // The block for a true condition, the actual predecessor block of the | 3186 // The block for a true condition, the actual predecessor block of the |
3170 // back edge. | 3187 // back edge. |
(...skipping 18 matching lines...) Expand all Loading... |
3189 break_info.break_block()); | 3206 break_info.break_block()); |
3190 set_current_block(loop_exit); | 3207 set_current_block(loop_exit); |
3191 } | 3208 } |
3192 | 3209 |
3193 | 3210 |
3194 void HGraphBuilder::VisitWhileStatement(WhileStatement* stmt) { | 3211 void HGraphBuilder::VisitWhileStatement(WhileStatement* stmt) { |
3195 ASSERT(!HasStackOverflow()); | 3212 ASSERT(!HasStackOverflow()); |
3196 ASSERT(current_block() != NULL); | 3213 ASSERT(current_block() != NULL); |
3197 ASSERT(current_block()->HasPredecessor()); | 3214 ASSERT(current_block()->HasPredecessor()); |
3198 ASSERT(current_block() != NULL); | 3215 ASSERT(current_block() != NULL); |
3199 PreProcessOsrEntry(stmt); | 3216 bool osr_entry = PreProcessOsrEntry(stmt); |
3200 HBasicBlock* loop_entry = CreateLoopHeaderBlock(); | 3217 HBasicBlock* loop_entry = CreateLoopHeaderBlock(); |
3201 current_block()->Goto(loop_entry); | 3218 current_block()->Goto(loop_entry); |
3202 set_current_block(loop_entry); | 3219 set_current_block(loop_entry); |
| 3220 if (osr_entry) graph()->set_osr_loop_entry(loop_entry); |
| 3221 |
3203 | 3222 |
3204 // If the condition is constant true, do not generate a branch. | 3223 // If the condition is constant true, do not generate a branch. |
3205 HBasicBlock* loop_successor = NULL; | 3224 HBasicBlock* loop_successor = NULL; |
3206 if (!stmt->cond()->ToBooleanIsTrue()) { | 3225 if (!stmt->cond()->ToBooleanIsTrue()) { |
3207 HBasicBlock* body_entry = graph()->CreateBasicBlock(); | 3226 HBasicBlock* body_entry = graph()->CreateBasicBlock(); |
3208 loop_successor = graph()->CreateBasicBlock(); | 3227 loop_successor = graph()->CreateBasicBlock(); |
3209 CHECK_BAILOUT(VisitForControl(stmt->cond(), body_entry, loop_successor)); | 3228 CHECK_BAILOUT(VisitForControl(stmt->cond(), body_entry, loop_successor)); |
3210 if (body_entry->HasPredecessor()) { | 3229 if (body_entry->HasPredecessor()) { |
3211 body_entry->SetJoinId(stmt->BodyId()); | 3230 body_entry->SetJoinId(stmt->BodyId()); |
3212 set_current_block(body_entry); | 3231 set_current_block(body_entry); |
(...skipping 21 matching lines...) Expand all Loading... |
3234 | 3253 |
3235 | 3254 |
3236 void HGraphBuilder::VisitForStatement(ForStatement* stmt) { | 3255 void HGraphBuilder::VisitForStatement(ForStatement* stmt) { |
3237 ASSERT(!HasStackOverflow()); | 3256 ASSERT(!HasStackOverflow()); |
3238 ASSERT(current_block() != NULL); | 3257 ASSERT(current_block() != NULL); |
3239 ASSERT(current_block()->HasPredecessor()); | 3258 ASSERT(current_block()->HasPredecessor()); |
3240 if (stmt->init() != NULL) { | 3259 if (stmt->init() != NULL) { |
3241 CHECK_ALIVE(Visit(stmt->init())); | 3260 CHECK_ALIVE(Visit(stmt->init())); |
3242 } | 3261 } |
3243 ASSERT(current_block() != NULL); | 3262 ASSERT(current_block() != NULL); |
3244 PreProcessOsrEntry(stmt); | 3263 bool osr_entry = PreProcessOsrEntry(stmt); |
3245 HBasicBlock* loop_entry = CreateLoopHeaderBlock(); | 3264 HBasicBlock* loop_entry = CreateLoopHeaderBlock(); |
3246 current_block()->Goto(loop_entry); | 3265 current_block()->Goto(loop_entry); |
3247 set_current_block(loop_entry); | 3266 set_current_block(loop_entry); |
| 3267 if (osr_entry) graph()->set_osr_loop_entry(loop_entry); |
3248 | 3268 |
3249 HBasicBlock* loop_successor = NULL; | 3269 HBasicBlock* loop_successor = NULL; |
3250 if (stmt->cond() != NULL) { | 3270 if (stmt->cond() != NULL) { |
3251 HBasicBlock* body_entry = graph()->CreateBasicBlock(); | 3271 HBasicBlock* body_entry = graph()->CreateBasicBlock(); |
3252 loop_successor = graph()->CreateBasicBlock(); | 3272 loop_successor = graph()->CreateBasicBlock(); |
3253 CHECK_BAILOUT(VisitForControl(stmt->cond(), body_entry, loop_successor)); | 3273 CHECK_BAILOUT(VisitForControl(stmt->cond(), body_entry, loop_successor)); |
3254 if (body_entry->HasPredecessor()) { | 3274 if (body_entry->HasPredecessor()) { |
3255 body_entry->SetJoinId(stmt->BodyId()); | 3275 body_entry->SetJoinId(stmt->BodyId()); |
3256 set_current_block(body_entry); | 3276 set_current_block(body_entry); |
3257 } | 3277 } |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3329 Push(start_index); | 3349 Push(start_index); |
3330 | 3350 |
3331 HInstruction* index_cache = AddInstruction( | 3351 HInstruction* index_cache = AddInstruction( |
3332 new(zone()) HForInCacheArray( | 3352 new(zone()) HForInCacheArray( |
3333 enumerable, | 3353 enumerable, |
3334 map, | 3354 map, |
3335 DescriptorArray::kEnumCacheBridgeIndicesCacheIndex)); | 3355 DescriptorArray::kEnumCacheBridgeIndicesCacheIndex)); |
3336 HForInCacheArray::cast(array)->set_index_cache( | 3356 HForInCacheArray::cast(array)->set_index_cache( |
3337 HForInCacheArray::cast(index_cache)); | 3357 HForInCacheArray::cast(index_cache)); |
3338 | 3358 |
3339 PreProcessOsrEntry(stmt); | 3359 bool osr_entry = PreProcessOsrEntry(stmt); |
3340 HBasicBlock* loop_entry = CreateLoopHeaderBlock(); | 3360 HBasicBlock* loop_entry = CreateLoopHeaderBlock(); |
3341 current_block()->Goto(loop_entry); | 3361 current_block()->Goto(loop_entry); |
3342 set_current_block(loop_entry); | 3362 set_current_block(loop_entry); |
| 3363 if (osr_entry) graph()->set_osr_loop_entry(loop_entry); |
3343 | 3364 |
3344 HValue* index = environment()->ExpressionStackAt(0); | 3365 HValue* index = environment()->ExpressionStackAt(0); |
3345 HValue* limit = environment()->ExpressionStackAt(1); | 3366 HValue* limit = environment()->ExpressionStackAt(1); |
3346 | 3367 |
3347 // Check that we still have more keys. | 3368 // Check that we still have more keys. |
3348 HCompareIDAndBranch* compare_index = | 3369 HCompareIDAndBranch* compare_index = |
3349 new(zone()) HCompareIDAndBranch(index, limit, Token::LT); | 3370 new(zone()) HCompareIDAndBranch(index, limit, Token::LT); |
3350 compare_index->SetInputRepresentation(Representation::Integer32()); | 3371 compare_index->SetInputRepresentation(Representation::Integer32()); |
3351 | 3372 |
3352 HBasicBlock* loop_body = graph()->CreateBasicBlock(); | 3373 HBasicBlock* loop_body = graph()->CreateBasicBlock(); |
(...skipping 4772 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8125 } | 8146 } |
8126 } | 8147 } |
8127 | 8148 |
8128 #ifdef DEBUG | 8149 #ifdef DEBUG |
8129 if (graph_ != NULL) graph_->Verify(false); // No full verify. | 8150 if (graph_ != NULL) graph_->Verify(false); // No full verify. |
8130 if (allocator_ != NULL) allocator_->Verify(); | 8151 if (allocator_ != NULL) allocator_->Verify(); |
8131 #endif | 8152 #endif |
8132 } | 8153 } |
8133 | 8154 |
8134 } } // namespace v8::internal | 8155 } } // namespace v8::internal |
OLD | NEW |