Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(117)

Side by Side Diff: src/hydrogen.cc

Issue 9425045: Support fast case for-in in Crankshaft. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: port to x64&arm, cleanup Created 8 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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 2724 matching lines...) Expand 10 before | Expand all | Expand 10 after
2735 } 2735 }
2736 2736
2737 HBasicBlock* join = CreateJoin(cond_true, cond_false, stmt->IfId()); 2737 HBasicBlock* join = CreateJoin(cond_true, cond_false, stmt->IfId());
2738 set_current_block(join); 2738 set_current_block(join);
2739 } 2739 }
2740 } 2740 }
2741 2741
2742 2742
2743 HBasicBlock* HGraphBuilder::BreakAndContinueScope::Get( 2743 HBasicBlock* HGraphBuilder::BreakAndContinueScope::Get(
2744 BreakableStatement* stmt, 2744 BreakableStatement* stmt,
2745 BreakType type) { 2745 BreakType type,
2746 int* drop_extra) {
2747 *drop_extra = 0;
2746 BreakAndContinueScope* current = this; 2748 BreakAndContinueScope* current = this;
2747 while (current != NULL && current->info()->target() != stmt) { 2749 while (current != NULL && current->info()->target() != stmt) {
2750 *drop_extra += current->info()->drop_extra();
2748 current = current->next(); 2751 current = current->next();
2749 } 2752 }
2750 ASSERT(current != NULL); // Always found (unless stack is malformed). 2753 ASSERT(current != NULL); // Always found (unless stack is malformed).
2754
2755 if (type == BREAK) {
2756 *drop_extra += current->info()->drop_extra();
2757 }
2758
2751 HBasicBlock* block = NULL; 2759 HBasicBlock* block = NULL;
2752 switch (type) { 2760 switch (type) {
2753 case BREAK: 2761 case BREAK:
2754 block = current->info()->break_block(); 2762 block = current->info()->break_block();
2755 if (block == NULL) { 2763 if (block == NULL) {
2756 block = current->owner()->graph()->CreateBasicBlock(); 2764 block = current->owner()->graph()->CreateBasicBlock();
2757 current->info()->set_break_block(block); 2765 current->info()->set_break_block(block);
2758 } 2766 }
2759 break; 2767 break;
2760 2768
2761 case CONTINUE: 2769 case CONTINUE:
2762 block = current->info()->continue_block(); 2770 block = current->info()->continue_block();
2763 if (block == NULL) { 2771 if (block == NULL) {
2764 block = current->owner()->graph()->CreateBasicBlock(); 2772 block = current->owner()->graph()->CreateBasicBlock();
2765 current->info()->set_continue_block(block); 2773 current->info()->set_continue_block(block);
2766 } 2774 }
2767 break; 2775 break;
2768 } 2776 }
2769 2777
2770 return block; 2778 return block;
2771 } 2779 }
2772 2780
2773 2781
2774 void HGraphBuilder::VisitContinueStatement(ContinueStatement* stmt) { 2782 void HGraphBuilder::VisitContinueStatement(ContinueStatement* stmt) {
2775 ASSERT(!HasStackOverflow()); 2783 ASSERT(!HasStackOverflow());
2776 ASSERT(current_block() != NULL); 2784 ASSERT(current_block() != NULL);
2777 ASSERT(current_block()->HasPredecessor()); 2785 ASSERT(current_block()->HasPredecessor());
2778 HBasicBlock* continue_block = break_scope()->Get(stmt->target(), CONTINUE); 2786 int drop_extra = 0;
2787 HBasicBlock* continue_block = break_scope()->Get(stmt->target(),
2788 CONTINUE,
2789 &drop_extra);
2790 Drop(drop_extra);
2779 current_block()->Goto(continue_block); 2791 current_block()->Goto(continue_block);
2780 set_current_block(NULL); 2792 set_current_block(NULL);
2781 } 2793 }
2782 2794
2783 2795
2784 void HGraphBuilder::VisitBreakStatement(BreakStatement* stmt) { 2796 void HGraphBuilder::VisitBreakStatement(BreakStatement* stmt) {
2785 ASSERT(!HasStackOverflow()); 2797 ASSERT(!HasStackOverflow());
2786 ASSERT(current_block() != NULL); 2798 ASSERT(current_block() != NULL);
2787 ASSERT(current_block()->HasPredecessor()); 2799 ASSERT(current_block()->HasPredecessor());
2788 HBasicBlock* break_block = break_scope()->Get(stmt->target(), BREAK); 2800 int drop_extra = 0;
2801 HBasicBlock* break_block = break_scope()->Get(stmt->target(),
2802 BREAK,
2803 &drop_extra);
2804 Drop(drop_extra);
2789 current_block()->Goto(break_block); 2805 current_block()->Goto(break_block);
2790 set_current_block(NULL); 2806 set_current_block(NULL);
2791 } 2807 }
2792 2808
2793 2809
2794 void HGraphBuilder::VisitReturnStatement(ReturnStatement* stmt) { 2810 void HGraphBuilder::VisitReturnStatement(ReturnStatement* stmt) {
2795 ASSERT(!HasStackOverflow()); 2811 ASSERT(!HasStackOverflow());
2796 ASSERT(current_block() != NULL); 2812 ASSERT(current_block() != NULL);
2797 ASSERT(current_block()->HasPredecessor()); 2813 ASSERT(current_block()->HasPredecessor());
2798 AstContext* context = call_context(); 2814 AstContext* context = call_context();
(...skipping 340 matching lines...) Expand 10 before | Expand all | Expand 10 after
3139 } 3155 }
3140 if (loop_successor->HasPredecessor()) { 3156 if (loop_successor->HasPredecessor()) {
3141 loop_successor->SetJoinId(stmt->ExitId()); 3157 loop_successor->SetJoinId(stmt->ExitId());
3142 } else { 3158 } else {
3143 loop_successor = NULL; 3159 loop_successor = NULL;
3144 } 3160 }
3145 } 3161 }
3146 3162
3147 BreakAndContinueInfo break_info(stmt); 3163 BreakAndContinueInfo break_info(stmt);
3148 if (current_block() != NULL) { 3164 if (current_block() != NULL) {
3149 BreakAndContinueScope push(&break_info, this);
3150 CHECK_BAILOUT(VisitLoopBody(stmt, loop_entry, &break_info)); 3165 CHECK_BAILOUT(VisitLoopBody(stmt, loop_entry, &break_info));
3151 } 3166 }
3152 HBasicBlock* body_exit = 3167 HBasicBlock* body_exit =
3153 JoinContinue(stmt, current_block(), break_info.continue_block()); 3168 JoinContinue(stmt, current_block(), break_info.continue_block());
3154 HBasicBlock* loop_exit = CreateLoop(stmt, 3169 HBasicBlock* loop_exit = CreateLoop(stmt,
3155 loop_entry, 3170 loop_entry,
3156 body_exit, 3171 body_exit,
3157 loop_successor, 3172 loop_successor,
3158 break_info.break_block()); 3173 break_info.break_block());
3159 set_current_block(loop_exit); 3174 set_current_block(loop_exit);
(...skipping 24 matching lines...) Expand all
3184 } 3199 }
3185 if (loop_successor->HasPredecessor()) { 3200 if (loop_successor->HasPredecessor()) {
3186 loop_successor->SetJoinId(stmt->ExitId()); 3201 loop_successor->SetJoinId(stmt->ExitId());
3187 } else { 3202 } else {
3188 loop_successor = NULL; 3203 loop_successor = NULL;
3189 } 3204 }
3190 } 3205 }
3191 3206
3192 BreakAndContinueInfo break_info(stmt); 3207 BreakAndContinueInfo break_info(stmt);
3193 if (current_block() != NULL) { 3208 if (current_block() != NULL) {
3194 BreakAndContinueScope push(&break_info, this);
3195 CHECK_BAILOUT(VisitLoopBody(stmt, loop_entry, &break_info)); 3209 CHECK_BAILOUT(VisitLoopBody(stmt, loop_entry, &break_info));
3196 } 3210 }
3197 HBasicBlock* body_exit = 3211 HBasicBlock* body_exit =
3198 JoinContinue(stmt, current_block(), break_info.continue_block()); 3212 JoinContinue(stmt, current_block(), break_info.continue_block());
3199 3213
3200 if (stmt->next() != NULL && body_exit != NULL) { 3214 if (stmt->next() != NULL && body_exit != NULL) {
3201 set_current_block(body_exit); 3215 set_current_block(body_exit);
3202 CHECK_BAILOUT(Visit(stmt->next())); 3216 CHECK_BAILOUT(Visit(stmt->next()));
3203 body_exit = current_block(); 3217 body_exit = current_block();
3204 } 3218 }
3205 3219
3206 HBasicBlock* loop_exit = CreateLoop(stmt, 3220 HBasicBlock* loop_exit = CreateLoop(stmt,
3207 loop_entry, 3221 loop_entry,
3208 body_exit, 3222 body_exit,
3209 loop_successor, 3223 loop_successor,
3210 break_info.break_block()); 3224 break_info.break_block());
3211 set_current_block(loop_exit); 3225 set_current_block(loop_exit);
3212 } 3226 }
3213 3227
3214 3228
3215 void HGraphBuilder::VisitForInStatement(ForInStatement* stmt) { 3229 void HGraphBuilder::VisitForInStatement(ForInStatement* stmt) {
3216 ASSERT(!HasStackOverflow()); 3230 ASSERT(!HasStackOverflow());
3217 ASSERT(current_block() != NULL); 3231 ASSERT(current_block() != NULL);
3218 ASSERT(current_block()->HasPredecessor()); 3232 ASSERT(current_block()->HasPredecessor());
3219 return Bailout("ForInStatement"); 3233
3234 if (!stmt->each()->IsVariableProxy() ||
3235 !stmt->each()->AsVariableProxy()->var()->IsStackLocal()) {
3236 return Bailout("ForInStatement with non-local each variable");
3237 }
3238
3239 Variable* each_var = stmt->each()->AsVariableProxy()->var();
3240
3241 CHECK_ALIVE(VisitForValue(stmt->enumerable()));
3242 HValue* enumerable = Top(); // Leave enumerable at the top.
3243
3244 HValue* context = environment()->LookupContext();
3245
3246 HInstruction* map = AddInstruction(new(zone()) HForInPrepareMap(
3247 context, enumerable));
3248 AddSimulate(stmt->PrepareId());
3249
3250 HInstruction* array = AddInstruction(
3251 new(zone()) HForInCacheArray(
3252 enumerable,
3253 map,
3254 DescriptorArray::kEnumCacheBridgeCacheIndex));
3255
3256 HInstruction* array_length = AddInstruction(
3257 new(zone()) HFixedArrayBaseLength(array));
3258
3259 HInstruction* start_index = AddInstruction(new(zone()) HConstant(
3260 Handle<Object>(Smi::FromInt(0)), Representation::Integer32()));
3261
3262 Push(map);
3263 Push(array);
3264 Push(array_length);
3265 Push(start_index);
3266
3267 HInstruction* index_cache = AddInstruction(
3268 new(zone()) HForInCacheArray(
3269 enumerable,
3270 map,
3271 DescriptorArray::kEnumCacheBridgeIndicesCacheIndex));
3272 HForInCacheArray::cast(array)->set_index_cache(
3273 HForInCacheArray::cast(index_cache));
3274
3275 HBasicBlock* loop_entry = CreateLoopHeaderBlock();
3276 current_block()->Goto(loop_entry);
3277 set_current_block(loop_entry);
3278
3279 HValue* index = Top();
3280
3281 // Check that we still have more keys.
3282 HCompareIDAndBranch* compare_index =
3283 new(zone()) HCompareIDAndBranch(index, array_length, Token::LT);
3284 compare_index->SetInputRepresentation(Representation::Integer32());
3285
3286 HBasicBlock* loop_body = graph()->CreateBasicBlock();
3287 HBasicBlock* loop_successor = graph()->CreateBasicBlock();
3288
3289 compare_index->SetSuccessorAt(0, loop_body);
3290 compare_index->SetSuccessorAt(1, loop_successor);
3291 current_block()->Finish(compare_index);
3292
3293 set_current_block(loop_successor);
3294 Drop(5);
3295
3296 set_current_block(loop_body);
3297
3298 HValue* key = AddInstruction(
3299 new(zone()) HLoadKeyedFastElement(
3300 array, index, HLoadKeyedFastElement::OMIT_HOLE_CHECK));
3301
3302 // Check if the expected map still matches that of the enumerable.
3303 // If not just deoptimize.
3304 AddInstruction(new(zone()) HCheckMapValue(enumerable, map));
3305
3306 Bind(each_var, key);
3307
3308 BreakAndContinueInfo break_info(stmt, 5);
3309 CHECK_BAILOUT(VisitLoopBody(stmt, loop_entry, &break_info));
3310
3311 HBasicBlock* body_exit =
3312 JoinContinue(stmt, current_block(), break_info.continue_block());
3313
3314 if (body_exit != NULL) {
3315 set_current_block(body_exit);
3316
3317 HValue* current_index = Pop();
3318 PushAndAdd(
3319 new(zone()) HAdd(context, current_index, graph()->GetConstant1()));
3320
3321 body_exit = current_block();
3322 }
3323
3324 HBasicBlock* loop_exit = CreateLoop(stmt,
3325 loop_entry,
3326 body_exit,
3327 loop_successor,
3328 break_info.break_block());
3329
3330 set_current_block(loop_exit);
3220 } 3331 }
3221 3332
3222 3333
3223 void HGraphBuilder::VisitTryCatchStatement(TryCatchStatement* stmt) { 3334 void HGraphBuilder::VisitTryCatchStatement(TryCatchStatement* stmt) {
3224 ASSERT(!HasStackOverflow()); 3335 ASSERT(!HasStackOverflow());
3225 ASSERT(current_block() != NULL); 3336 ASSERT(current_block() != NULL);
3226 ASSERT(current_block()->HasPredecessor()); 3337 ASSERT(current_block()->HasPredecessor());
3227 return Bailout("TryCatchStatement"); 3338 return Bailout("TryCatchStatement");
3228 } 3339 }
3229 3340
(...skipping 4528 matching lines...) Expand 10 before | Expand all | Expand 10 after
7758 } 7869 }
7759 } 7870 }
7760 7871
7761 #ifdef DEBUG 7872 #ifdef DEBUG
7762 if (graph_ != NULL) graph_->Verify(false); // No full verify. 7873 if (graph_ != NULL) graph_->Verify(false); // No full verify.
7763 if (allocator_ != NULL) allocator_->Verify(); 7874 if (allocator_ != NULL) allocator_->Verify();
7764 #endif 7875 #endif
7765 } 7876 }
7766 7877
7767 } } // namespace v8::internal 7878 } } // namespace v8::internal
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698