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

Unified Diff: src/code-stubs-hydrogen.cc

Issue 12385014: Hydrogen stubs for array constructors (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: More efficient code when number of arguments is known Created 7 years, 8 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/code-stubs.cc ('k') | src/compiler.cc » ('j') | src/hydrogen.cc » ('J')
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/code-stubs-hydrogen.cc
diff --git a/src/code-stubs-hydrogen.cc b/src/code-stubs-hydrogen.cc
index 18dfcac11f510975bcf10c0effd500317149b9bc..f0841f9ae5f0012fa12d4155663762a7c4b1f137 100644
--- a/src/code-stubs-hydrogen.cc
+++ b/src/code-stubs-hydrogen.cc
@@ -132,9 +132,13 @@ bool CodeStubGraphBuilderBase::BuildGraph() {
HParameter::REGISTER_PARAMETER,
Representation::Integer32());
// it's essential to bind this value to the environment in case of deopt
- start_environment->Bind(param_count, stack_parameter_count);
AddInstruction(stack_parameter_count);
- arguments_length_ = stack_parameter_count;
+ start_environment->Bind(param_count, stack_parameter_count);
+ arguments_length_ = AddInstruction(new(zone) HChange(
+ stack_parameter_count,
+ Representation::Tagged(),
+ true,
+ false));
} else {
ASSERT(descriptor_->environment_length() == param_count);
stack_parameter_count = graph()->GetConstantMinus1();
@@ -402,12 +406,29 @@ Handle<Code> TransitionElementsKindStub::GenerateCode() {
}
+// #define NOARG_DEOPT
+// #define ONEARG_DEOPT
+// #define NARG_DEOPT
template <>
HValue* CodeStubGraphBuilder<ArrayNoArgumentConstructorStub>::BuildCodeStub() {
+ // ----------- S t a t e -------------
+ // -- Parameter 1 : type info cell
+ // -- Parameter 0 : constructor
+ // -----------------------------------
+#ifdef NOARG_DEOPT
HInstruction* deopt = new(zone()) HSoftDeoptimize();
AddInstruction(deopt);
current_block()->MarkAsDeoptimizing();
return GetParameter(0);
+#else
+ // Get the right map
+ // Should be a constant
+ JSArrayBuilder array_builder(this,
+ casted_stub()->elements_kind(),
+ GetParameter(ArrayConstructorStubBase::kPropertyCell));
+ HValue* new_object = array_builder.AllocateEmptyArray();
+ return new_object;
+#endif
}
@@ -419,10 +440,58 @@ Handle<Code> ArrayNoArgumentConstructorStub::GenerateCode() {
template <>
HValue* CodeStubGraphBuilder<ArraySingleArgumentConstructorStub>::
BuildCodeStub() {
+#ifdef ONEARG_DEOPT
HInstruction* deopt = new(zone()) HSoftDeoptimize();
AddInstruction(deopt);
current_block()->MarkAsDeoptimizing();
return GetParameter(0);
+#else
+ // Smi check and range check on the input arg.
+ HValue* constant_one = graph()->GetConstant1();
+ HValue* constant_zero = graph()->GetConstant0();
+
+ HInstruction* elements = AddInstruction(
+ new(zone()) HArgumentsElements(false));
+ HInstruction* argument = AddInstruction(
+ new(zone()) HAccessArgumentsAt(elements, constant_one, constant_zero));
+
+ HConstant* max_alloc_length =
+ new(zone()) HConstant(JSObject::kInitialMaxFastElementArray,
+ Representation::Tagged());
+ AddInstruction(max_alloc_length);
+ const int initial_capacity = JSArray::kPreallocatedArrayElements;
+ HConstant* initial_capacity_node =
+ new(zone()) HConstant(initial_capacity, Representation::Tagged());
+ AddInstruction(initial_capacity_node);
+
+ // Since we're forcing Integer32 representation for this HBoundsCheck,
+ // there's no need to Smi-check the index.
+ HBoundsCheck* checked_arg = AddBoundsCheck(argument, max_alloc_length,
+ ALLOW_SMI_KEY,
+ Representation::Tagged());
+ IfBuilder if_builder(this);
+ if_builder.BeginIf(checked_arg, constant_zero, Token::EQ);
+ Push(initial_capacity_node); // capacity
+ Push(constant_zero); // length
+ if_builder.BeginElse();
+ Push(checked_arg); // capacity
+ Push(checked_arg); // length
+ if_builder.End();
+
+ // Figure out total size
+ HValue* length = Pop();
+ HValue* capacity = Pop();
+
+ JSArrayBuilder array_builder(this,
+ casted_stub()->elements_kind(),
+ GetParameter(ArrayConstructorStubBase::kPropertyCell));
+ HValue* size_in_bytes = array_builder.EstablishAllocationSize(capacity);
+ HValue* new_object = array_builder.AllocateArray(size_in_bytes,
+ capacity,
+ length,
+ true);
+ return new_object;
+#endif
}
@@ -433,10 +502,54 @@ Handle<Code> ArraySingleArgumentConstructorStub::GenerateCode() {
template <>
HValue* CodeStubGraphBuilder<ArrayNArgumentsConstructorStub>::BuildCodeStub() {
+#ifdef NARG_DEOPT
HInstruction* deopt = new(zone()) HSoftDeoptimize();
AddInstruction(deopt);
current_block()->MarkAsDeoptimizing();
return GetParameter(0);
+#else
+ ElementsKind kind = casted_stub()->elements_kind();
+ HValue* length = GetArgumentsLength();
+
+ JSArrayBuilder array_builder(this,
+ kind,
+ GetParameter(ArrayConstructorStubBase::kPropertyCell));
+
+ HValue* total_size = array_builder.EstablishAllocationSize(length);
+ // We need to fill with the hole if it's a smi array in the multi-argument
+ // case because we might have to bail out while copying arguments into
+ // the array because they aren't compatible with a smi array.
+ // If it's a double array, no problem, and if it's fast then no
+ // problem either because doubles are boxed.
+ bool fill_with_hole = IsFastSmiElementsKind(kind);
+ HValue* new_object = array_builder.AllocateArray(total_size,
+ length,
+ length,
+ fill_with_hole);
+ HValue* elements = array_builder.GetElementsLocation();
+ ASSERT(elements != NULL);
+
+ // Now populate the elements correctly.
+ LoopBuilder builder(this,
+ context(),
+ LoopBuilder::kPostIncrement);
+ HValue* start = graph()->GetConstant0();
+ HValue* key = builder.BeginBody(start, length, Token::LT);
+ HInstruction* argument_elements = AddInstruction(
+ new(zone()) HArgumentsElements(false));
+ HInstruction* argument = AddInstruction(new(zone()) HAccessArgumentsAt(
+ argument_elements, length, key));
+
+ // Checks to prevent incompatible stores
+ if (IsFastSmiElementsKind(kind)) {
+ AddInstruction(new(zone()) HCheckSmi(argument));
+ }
+
+ AddInstruction(new(zone()) HStoreKeyed(elements, key, argument, kind));
+ AddSimulate(BailoutId::StubEntry(), REMOVABLE_SIMULATE);
+ builder.EndBody();
+ return new_object;
+#endif
}
« no previous file with comments | « src/code-stubs.cc ('k') | src/compiler.cc » ('j') | src/hydrogen.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698