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

Unified 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, 1 month 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 side-by-side diff with in-line comments
Download patch
Index: src/hydrogen.cc
diff --git a/src/hydrogen.cc b/src/hydrogen.cc
index 5c0703bc37434ea91b475990e4f09349a596b2c2..d4e666ffdef00a1ee96746792c1395ba2e85f54a 100644
--- a/src/hydrogen.cc
+++ b/src/hydrogen.cc
@@ -3457,73 +3457,70 @@ void HGraphBuilder::VisitArrayLiteral(ArrayLiteral* expr) {
int length = subexprs->length();
HValue* context = environment()->LookupContext();
- HArrayLiteral* literal = new(zone()) HArrayLiteral(context,
- expr->constant_elements(),
- length,
- expr->literal_index(),
- expr->depth());
- // The array is expected in the bailout environment during computation
- // of the property values and is the value of the entire expression.
- PushAndAdd(literal);
-
- HLoadElements* elements = NULL;
-
- for (int i = 0; i < length; i++) {
- Expression* subexpr = subexprs->at(i);
- // If the subexpression is a literal or a simple materialized literal it
- // is already set in the cloned array.
- if (CompileTimeValue::IsCompileTimeValue(subexpr)) continue;
+ FixedArray* literals = environment()->closure()->literals();
+ Handle<Object> raw_boilerplate(literals->get(expr->literal_index()));
- CHECK_ALIVE(VisitForValue(subexpr));
- HValue* value = Pop();
- if (!Smi::IsValid(i)) return Bailout("Non-smi key in array literal");
-
- elements = new(zone()) HLoadElements(literal);
- AddInstruction(elements);
-
- HValue* key = AddInstruction(
- new(zone()) HConstant(Handle<Object>(Smi::FromInt(i)),
- Representation::Integer32()));
- HInstruction* elements_kind =
- AddInstruction(new(zone()) HElementsKind(literal));
- HBasicBlock* store_fast = graph()->CreateBasicBlock();
- // Two empty blocks to satisfy edge split form.
- HBasicBlock* store_fast_edgesplit1 = graph()->CreateBasicBlock();
- HBasicBlock* store_fast_edgesplit2 = graph()->CreateBasicBlock();
- HBasicBlock* store_generic = graph()->CreateBasicBlock();
- HBasicBlock* check_smi_only_elements = graph()->CreateBasicBlock();
- HBasicBlock* join = graph()->CreateBasicBlock();
-
- HIsSmiAndBranch* smicheck = new(zone()) HIsSmiAndBranch(value);
- smicheck->SetSuccessorAt(0, store_fast_edgesplit1);
- smicheck->SetSuccessorAt(1, check_smi_only_elements);
- current_block()->Finish(smicheck);
- store_fast_edgesplit1->Finish(new(zone()) HGoto(store_fast));
-
- set_current_block(check_smi_only_elements);
- HCompareConstantEqAndBranch* smi_elements_check =
- new(zone()) HCompareConstantEqAndBranch(elements_kind,
- FAST_ELEMENTS,
- Token::EQ_STRICT);
- smi_elements_check->SetSuccessorAt(0, store_fast_edgesplit2);
- smi_elements_check->SetSuccessorAt(1, store_generic);
- current_block()->Finish(smi_elements_check);
- store_fast_edgesplit2->Finish(new(zone()) HGoto(store_fast));
-
- set_current_block(store_fast);
- AddInstruction(new(zone()) HStoreKeyedFastElement(elements, key, value));
- store_fast->Goto(join);
-
- set_current_block(store_generic);
- AddInstruction(BuildStoreKeyedGeneric(literal, key, value));
- store_generic->Goto(join);
-
- join->SetJoinId(expr->id());
- set_current_block(join);
+ // For now, no boilerplate causes a deopt.
+ if (raw_boilerplate->IsUndefined()) {
+ AddInstruction(new(zone()) HSoftDeoptimize);
+ return ast_context()->ReturnValue(graph()->GetConstantUndefined());
+ } 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.
+ Handle<JSObject> boilerplate(Handle<JSObject>::cast(raw_boilerplate));
+ ElementsKind boilerplate_elements_kind = boilerplate->GetElementsKind();
+
+ HArrayLiteral* literal = new(zone()) HArrayLiteral(
+ context,
+ boilerplate,
+ length,
+ expr->literal_index(),
+ expr->depth());
+
+ // The array is expected in the bailout environment during computation
+ // of the property values and is the value of the entire expression.
+ PushAndAdd(literal);
+
+ HLoadElements* elements = NULL;
+
+ for (int i = 0; i < length; i++) {
+ Expression* subexpr = subexprs->at(i);
+ // If the subexpression is a literal or a simple materialized literal it
+ // is already set in the cloned array.
+ if (CompileTimeValue::IsCompileTimeValue(subexpr)) continue;
+
+ CHECK_ALIVE(VisitForValue(subexpr));
+ HValue* value = Pop();
+ if (!Smi::IsValid(i)) return Bailout("Non-smi key in array literal");
+
+ elements = new(zone()) HLoadElements(literal);
+ AddInstruction(elements);
+
+ HValue* key = AddInstruction(
+ new(zone()) HConstant(Handle<Object>(Smi::FromInt(i)),
+ Representation::Integer32()));
+
+ switch (boilerplate_elements_kind) {
+ case FAST_SMI_ONLY_ELEMENTS:
+ case FAST_ELEMENTS:
+ 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.
+ elements,
+ key,
+ value,
+ boilerplate_elements_kind));
+ break;
+ case FAST_DOUBLE_ELEMENTS:
+ AddInstruction(new(zone()) HStoreKeyedFastDoubleElement(elements,
+ key,
+ value));
+ break;
+ default:
+ UNREACHABLE();
+ break;
+ }
- AddSimulate(expr->GetIdForElement(i));
+ AddSimulate(expr->GetIdForElement(i));
+ }
+ return ast_context()->ReturnValue(Pop());
}
- return ast_context()->ReturnValue(Pop());
}

Powered by Google App Engine
This is Rietveld 408576698