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

Side by Side Diff: src/hydrogen.cc

Issue 8747009: Optimize Crankshaft array literal initialization from boilerplate. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: fix stuff Created 9 years 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 2011 the V8 project authors. All rights reserved. 1 // Copyright 2011 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 3439 matching lines...) Expand 10 before | Expand all | Expand 10 after
3450 3450
3451 3451
3452 void HGraphBuilder::VisitArrayLiteral(ArrayLiteral* expr) { 3452 void HGraphBuilder::VisitArrayLiteral(ArrayLiteral* expr) {
3453 ASSERT(!HasStackOverflow()); 3453 ASSERT(!HasStackOverflow());
3454 ASSERT(current_block() != NULL); 3454 ASSERT(current_block() != NULL);
3455 ASSERT(current_block()->HasPredecessor()); 3455 ASSERT(current_block()->HasPredecessor());
3456 ZoneList<Expression*>* subexprs = expr->values(); 3456 ZoneList<Expression*>* subexprs = expr->values();
3457 int length = subexprs->length(); 3457 int length = subexprs->length();
3458 HValue* context = environment()->LookupContext(); 3458 HValue* context = environment()->LookupContext();
3459 3459
3460 HArrayLiteral* literal = new(zone()) HArrayLiteral(context, 3460 FixedArray* literals = environment()->closure()->literals();
3461 expr->constant_elements(), 3461 Handle<Object> raw_boilerplate(literals->get(expr->literal_index()));
3462 length,
3463 expr->literal_index(),
3464 expr->depth());
3465 // The array is expected in the bailout environment during computation
3466 // of the property values and is the value of the entire expression.
3467 PushAndAdd(literal);
3468 3462
3469 HLoadElements* elements = NULL; 3463 // For now, no boilerplate causes a deopt.
3464 if (raw_boilerplate->IsUndefined()) {
3465 AddInstruction(new(zone()) HSoftDeoptimize);
3466 return ast_context()->ReturnValue(graph()->GetConstantUndefined());
3467 } else {
Jakob Kummerow 2011/11/30 14:04:51 Since the if-branch ends with a return statement,
danno 2011/12/01 14:41:11 Done.
3468 Handle<JSObject> boilerplate(Handle<JSObject>::cast(raw_boilerplate));
3469 ElementsKind boilerplate_elements_kind = boilerplate->GetElementsKind();
3470 3470
3471 for (int i = 0; i < length; i++) { 3471 HArrayLiteral* literal = new(zone()) HArrayLiteral(
3472 Expression* subexpr = subexprs->at(i); 3472 context,
3473 // If the subexpression is a literal or a simple materialized literal it 3473 boilerplate,
3474 // is already set in the cloned array. 3474 length,
3475 if (CompileTimeValue::IsCompileTimeValue(subexpr)) continue; 3475 expr->literal_index(),
3476 expr->depth());
3476 3477
3477 CHECK_ALIVE(VisitForValue(subexpr)); 3478 // The array is expected in the bailout environment during computation
3478 HValue* value = Pop(); 3479 // of the property values and is the value of the entire expression.
3479 if (!Smi::IsValid(i)) return Bailout("Non-smi key in array literal"); 3480 PushAndAdd(literal);
3480 3481
3481 elements = new(zone()) HLoadElements(literal); 3482 HLoadElements* elements = NULL;
3482 AddInstruction(elements);
3483 3483
3484 HValue* key = AddInstruction( 3484 for (int i = 0; i < length; i++) {
3485 new(zone()) HConstant(Handle<Object>(Smi::FromInt(i)), 3485 Expression* subexpr = subexprs->at(i);
3486 Representation::Integer32())); 3486 // If the subexpression is a literal or a simple materialized literal it
3487 HInstruction* elements_kind = 3487 // is already set in the cloned array.
3488 AddInstruction(new(zone()) HElementsKind(literal)); 3488 if (CompileTimeValue::IsCompileTimeValue(subexpr)) continue;
3489 HBasicBlock* store_fast = graph()->CreateBasicBlock();
3490 // Two empty blocks to satisfy edge split form.
3491 HBasicBlock* store_fast_edgesplit1 = graph()->CreateBasicBlock();
3492 HBasicBlock* store_fast_edgesplit2 = graph()->CreateBasicBlock();
3493 HBasicBlock* store_generic = graph()->CreateBasicBlock();
3494 HBasicBlock* check_smi_only_elements = graph()->CreateBasicBlock();
3495 HBasicBlock* join = graph()->CreateBasicBlock();
3496 3489
3497 HIsSmiAndBranch* smicheck = new(zone()) HIsSmiAndBranch(value); 3490 CHECK_ALIVE(VisitForValue(subexpr));
3498 smicheck->SetSuccessorAt(0, store_fast_edgesplit1); 3491 HValue* value = Pop();
3499 smicheck->SetSuccessorAt(1, check_smi_only_elements); 3492 if (!Smi::IsValid(i)) return Bailout("Non-smi key in array literal");
3500 current_block()->Finish(smicheck);
3501 store_fast_edgesplit1->Finish(new(zone()) HGoto(store_fast));
3502 3493
3503 set_current_block(check_smi_only_elements); 3494 elements = new(zone()) HLoadElements(literal);
3504 HCompareConstantEqAndBranch* smi_elements_check = 3495 AddInstruction(elements);
3505 new(zone()) HCompareConstantEqAndBranch(elements_kind,
3506 FAST_ELEMENTS,
3507 Token::EQ_STRICT);
3508 smi_elements_check->SetSuccessorAt(0, store_fast_edgesplit2);
3509 smi_elements_check->SetSuccessorAt(1, store_generic);
3510 current_block()->Finish(smi_elements_check);
3511 store_fast_edgesplit2->Finish(new(zone()) HGoto(store_fast));
3512 3496
3513 set_current_block(store_fast); 3497 HValue* key = AddInstruction(
3514 AddInstruction(new(zone()) HStoreKeyedFastElement(elements, key, value)); 3498 new(zone()) HConstant(Handle<Object>(Smi::FromInt(i)),
3515 store_fast->Goto(join); 3499 Representation::Integer32()));
3516 3500
3517 set_current_block(store_generic); 3501 switch (boilerplate_elements_kind) {
3518 AddInstruction(BuildStoreKeyedGeneric(literal, key, value)); 3502 case FAST_SMI_ONLY_ELEMENTS:
3519 store_generic->Goto(join); 3503 case FAST_ELEMENTS:
3504 AddInstruction(new(zone()) HStoreKeyedFastElement(
Jakob Kummerow 2011/11/30 14:04:51 Hm... this will deopt if |value| doesn't match |bo
danno 2011/12/01 14:41:11 Done.
3505 elements,
3506 key,
3507 value,
3508 boilerplate_elements_kind));
3509 break;
3510 case FAST_DOUBLE_ELEMENTS:
3511 AddInstruction(new(zone()) HStoreKeyedFastDoubleElement(elements,
3512 key,
3513 value));
3514 break;
3515 default:
3516 UNREACHABLE();
3517 break;
3518 }
3520 3519
3521 join->SetJoinId(expr->id()); 3520 AddSimulate(expr->GetIdForElement(i));
3522 set_current_block(join); 3521 }
3523 3522 return ast_context()->ReturnValue(Pop());
3524 AddSimulate(expr->GetIdForElement(i));
3525 } 3523 }
3526 return ast_context()->ReturnValue(Pop());
3527 } 3524 }
3528 3525
3529 3526
3530 // Sets the lookup result and returns true if the store can be inlined. 3527 // Sets the lookup result and returns true if the store can be inlined.
3531 static bool ComputeStoredField(Handle<Map> type, 3528 static bool ComputeStoredField(Handle<Map> type,
3532 Handle<String> name, 3529 Handle<String> name,
3533 LookupResult* lookup) { 3530 LookupResult* lookup) {
3534 type->LookupInDescriptors(NULL, *name, lookup); 3531 type->LookupInDescriptors(NULL, *name, lookup);
3535 if (!lookup->IsPropertyOrTransition()) return false; 3532 if (!lookup->IsPropertyOrTransition()) return false;
3536 if (lookup->type() == FIELD) return true; 3533 if (lookup->type() == FIELD) return true;
(...skipping 3687 matching lines...) Expand 10 before | Expand all | Expand 10 after
7224 } 7221 }
7225 } 7222 }
7226 7223
7227 #ifdef DEBUG 7224 #ifdef DEBUG
7228 if (graph_ != NULL) graph_->Verify(false); // No full verify. 7225 if (graph_ != NULL) graph_->Verify(false); // No full verify.
7229 if (allocator_ != NULL) allocator_->Verify(); 7226 if (allocator_ != NULL) allocator_->Verify();
7230 #endif 7227 #endif
7231 } 7228 }
7232 7229
7233 } } // namespace v8::internal 7230 } } // namespace v8::internal
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698